前言
引入
前面的文章已经完成了服务之间的调用,但是我们怎么才能实现外部调用服务的接口呢。
首先我们可以把通过直接调用 公网ip 端口 的形式进行调用,这种方式肯定是可行的,但是这样直接把ip和端口暴露出来,肯定是不安全的,万一有大佬把你的服务器黑了,这就有点难受了(曾经被清理过数据库数据的受害者表示 我一个学生的服务器你黑个什么劲)。
这时候我们就引入一个名词–反向代理
通俗来讲,当你调用某一个服务的接口时是不会直接访问这个接口的真实地址,而是向代理服务器发送请求,由代理服务器向其他服务进行请求的转发,在服务处理结束之后就将结果返回给代理服务器,再由代理服务器将结果转发给你
这个过程中用户并不知道自己调用的是代理服务器,用户认为自己就是在调用真实服务的地址,这个过程就成为反向代理。详情可以看下这个简单聊聊我理解的正向代理和反向代理吧,纯大白话
GateWay作用
Gateway其实就是起到反向代理的作用,也可以认为网关就是所有服务的入口,如果硬件支持的话,我自己认为比较简单的架构如下图所示
其实可以多设置几层nginx在进行一层代理,这样就能处理更多的并发量。
Gateway整合nacos实现反向代理
pom.xml
如下为要引入的依赖
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>test</artifactId>
<groupId>com.xiaow</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- <dependencies>-->
<!-- 配置依赖关系 -->
<dependencies>
<dependency>
<groupId>com.xiaow</groupId>
<artifactId>common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>com.xiaow</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--fastjson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.xiaow.test.Provider8001</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
配置文件
主要是routes的配置
routes讲解
代码语言:javascript复制 routes:
- id: consumer #设置路由id(理论上是可以随便写的)
uri: lb://consumer #设置路由的url lb://nacos服务注册名称
filters:
- StripPrefix=1
predicates:
- Path=/one/** #路径匹配规则
如上述配置
id 只是配置一个路由的id,这个id是随便写就可以,但是不能重复。
uri: lb:consumer consumer对应的就是Nacos中的注册的服务名
Path 就是一个匹配路径
例如consumer服务的接口调用是 /get,那么通过网关调用,路径就是/one/get
全部配置文件
代码语言:javascript复制在server:
port: 8050 #服务端口
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: http://192.168.30.1:8848/
gateway:
discovery:
locator:
enabled: true #使用服务发现路由
routes:
- id: consumer #设置路由id(理论上是可以随便写的)
uri: lb://consumer #设置路由的url lb://nacos服务注册名称
filters:
- StripPrefix=1
predicates:
- Path=/one/** #路径匹配规则
- id: provider
uri: lb://provider
filters:
- StripPrefix=1
predicates:
- Path=/two/** #路径匹配规则
- id: account
uri: lb://account
filters:
- StripPrefix=1
predicates:
- Path=/account/** #路径匹配规则
management:
endpoints:
web:
exposure:
include: "*"
处理跨域
代码语言:javascript复制package com.xiaow.gateway.config;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;
import java.util.stream.Collectors;
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}
启动类
代码语言:javascript复制package com.xiaow.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Gateway8050 {
public static void main(String[] args) {
SpringApplication.run(Gateway8050.class,args);
}
}
总结
还是复习,完整项目已传入码云
码云链接