SpringCloud+Gateway+Nacos+Sentinel
1、实现Gateway路由动态加载
2、在Gateway动态修改RequestBody内容,实现网关加解密
3、实现Sentinel流控规则落地到Nacos,并动态加载:sentinel-dashboard -> Nacos 以及 Nacos -> sentinel-dashboard
顶级模块 pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xxx</groupId>
<artifactId>xxx-gateway-parent</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<description>Spring Boot Gateway</description>
<modules>
<module>xxx-gateway</module>
<module>user-service</module>
<module>order-service</module>
</modules>
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
<!-- Alibaba 的JSON处理库 -->
<alibaba.fastjson.version>1.2.83</alibaba.fastjson.version>
<alibaba.fastjson-yaml.version>2.6.2</alibaba.fastjson-yaml.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<!-- Alibaba 的JSON处理库 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 声明springBoot版本 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 声明springCloud版本 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 声明 springCloud Alibaba 版本 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Alibaba 的JSON处理库 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${alibaba.fastjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration><encoding>UTF-8</encoding>
<!-- 过滤后缀为pem、pfx的证书文件 -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>cer</nonFilteredFileExtension>
<nonFilteredFileExtension>pem</nonFilteredFileExtension>
<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
</project>
网关模块 pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxx</groupId>
<artifactId>xxx-gateway</artifactId>
<version>1.0.0-SNAPSHOT</version>
<description>SpringCloud Alibaba Gateway</description>
<parent>
<groupId>com.xxx</groupId>
<artifactId>xxx-gateway-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 使用阿里云的nacos作为注册中心和配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 阿里巴巴 Nacos 配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 引入sentinel进行服务降级熔断 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- gateway网关整合sentinel进行限流降级 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- 使用Nacos保存流控规则 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- 引入 Redis spring-boot-starter-cache 依赖 与 Pool2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
网关模块 bootstrap.yml
server:
port: 9090
spring:
application:
name: gateway-service
cloud:
nacos:
username: nacos
password: nacos
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yml
# 路由配置放到 Nacos 上管理
# gateway:
# discovery:
# locator:
# # gateway 可以从 nacos 发现微服务
# enabled: true
# globalcors:
# cors-configurations:
# '[/**]':
# allowedOrigins: "*"
# allowedMethods: "*"
# allowedHeaders: "*"
# filter:
# modify-request-body:
# enabled: true
# routes:
# - id: order-api-9002
# uri: lb://order-service
# predicates:
# - Path=/order-api/**
# filters:
# - RewritePath=/order-api(?<segment>/?.*), $\{segment}
sentinel:
# 服务启动就建立心跳连接
eager: true
transport:
# 控制台地址
dashboard: localhost:8080
scg:
fallback:
mode: response
response-status: 426
response-body: '{"code": 426, "message": "限流了,稍后重试!"}'
datasource:
### nacos连接地址
nacos:
server-addr: 127.0.0.1:8848
# 自定义命名
ds1:
# 支持多种持久化数据源:file、nacos、zk、apollo、redis、consul
nacos:
## nacos连接的分组
group-id: ${sentinel.nacos.gw-flow.group-id}
# 规则类型:flow、degrade、param-flow、system、authority、gw-flow、gw-api-group
rule-type: gw-flow
### 读取配置文件的 data-id
data-id: ${sentinel.nacos.gw-flow.data-id}
### 读取配置文件类型为json
data-type: ${sentinel.nacos.gw-flow.data-type}
sentinel:
nacos:
gw-flow:
group-id: DEFAULT_GROUP
data-id: gateway-sentinel-flowrule.json
data-type: json
gateway-service.yml
spring:
cloud:
gateway:
discovery:
locator:
# gateway 可以从 nacos 发现微服务
enabled: false
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
filter:
modify-request-body:
enabled: true
routes:
- id: order-api-9002
uri: lb://order-service
predicates:
- Path=/order-api/**
filters:
- RewritePath=/order-api(?<segment>/?.*), $\{segment}
- id: order-api2-9002
uri: lb://order-service
predicates:
- Path=/order-api2/**
filters:
- RewritePath=/order-api2(?<segment>/?.*), $\{segment}
动态修改 RequestBody 以及 动态刷新 路由配置
在启动类:GatewayApplication.java 添加 RouteLocator bean 注入
package com.xxx.gateway;
import com.alibaba.fastjson.JSONObject;
import com.xxx.gateway.filter.ModifyRequestBodyRewriteFunction;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@RefreshScope
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("user_api_rout", r -> r.path("/user-api/**")
.filters(f -> f.stripPrefix(1)
.modifyRequestBody(config ->
config.setInClass(JSONObject.class)
.setOutClass(JSONObject.class)
.setRewriteFunction(new ModifyRequestBodyRewriteFunction())
))
.uri("lb://user-service")
)
.build();
}
}
修改请求体:ModifyRequestBodyRewriteFunction.java
package com.xxx.gateway.filter;
import com.alibaba.fastjson.JSONObject;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 修改请求体
* @date 2023/8/27 13:18
*/
@Component
public class ModifyRequestBodyRewriteFunction implements RewriteFunction<JSONObject, JSONObject> {
@Override
public Publisher<JSONObject> apply(ServerWebExchange serverWebExchange, JSONObject o) {
if (o == null) {
return Mono.empty();
}
o.put("name", "我是不请自来");
return Mono.just(o);
}
}