Spring Cloud Sentinel 与 Spring Cloud Gateway 整合,实现微服务的集群流控

下面就看看Gateway 如何与Sentinel进行服务的统一流控

创建一个统一的父工程,管理Gateway项目以及微服务项目

Sentinel与Gateway整合实现微服务的集群流控 - 图1

修改父工程的pom,创建统一的依赖管理

  1. <!--统一管理jar包版本-->
  2. <properties>
  3. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  4. <maven.compiler.source>1.8</maven.compiler.source>
  5. <maven.compiler.target>1.8</maven.compiler.target>
  6. <junit.version>4.12</junit.version>
  7. <log4j.version>1.2.17</log4j.version>
  8. <lombok.version>1.16.18</lombok.version>
  9. <mysql.version>8.0.19</mysql.version>
  10. <druid.version>1.1.16</druid.version>
  11. <spring.boot.version>2.2.2.RELEASE</spring.boot.version>
  12. <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
  13. <spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version>
  14. <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
  15. <knife4j.version>2.0.4</knife4j.version>
  16. </properties>
  17. <!--子模块继承后,提供作用:锁定版本+子module不用groupId和version-->
  18. <dependencyManagement>
  19. <dependencies>
  20. <!--springboot 2.2.2-->
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-dependencies</artifactId>
  24. <version>${spring.boot.version}</version>
  25. <type>pom</type>
  26. <scope>import</scope>
  27. </dependency>
  28. <!--Spring cloud Hoxton.SR1-->
  29. <dependency>
  30. <groupId>org.springframework.cloud</groupId>
  31. <artifactId>spring-cloud-dependencies</artifactId>
  32. <version>${spring.cloud.version}</version>
  33. <type>pom</type>
  34. <scope>import</scope>
  35. </dependency>
  36. <!--Spring cloud alibaba 2.1.0.RELEASE-->
  37. <dependency>
  38. <groupId>com.alibaba.cloud</groupId>
  39. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  40. <version>${spring.cloud.alibaba.version}</version>
  41. <type>pom</type>
  42. <scope>import</scope>
  43. </dependency>
  44. <dependency>
  45. <groupId>mysql</groupId>
  46. <artifactId>mysql-connector-java</artifactId>
  47. <version>${mysql.version}</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>com.alibaba</groupId>
  51. <artifactId>druid</artifactId>
  52. <version>${druid.version}</version>
  53. </dependency>
  54. <dependency>
  55. <groupId>org.projectlombok</groupId>
  56. <artifactId>lombok</artifactId>
  57. <version>${lombok.version}</version>
  58. </dependency>
  59. <!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-micro-spring-boot-starter -->
  60. <dependency>
  61. <groupId>com.github.xiaoymin</groupId>
  62. <artifactId>knife4j-micro-spring-boot-starter</artifactId>
  63. <version>${knife4j.version}</version>
  64. </dependency>
  65. </dependencies>
  66. </dependencyManagement>
  67. <build>
  68. <plugins>
  69. <plugin>
  70. <groupId>org.springframework.boot</groupId>
  71. <artifactId>spring-boot-maven-plugin</artifactId>
  72. <version>${spring.boot.version}</version>
  73. <configuration>
  74. <fork>true</fork>
  75. <addResources>true</addResources>
  76. </configuration>
  77. </plugin>
  78. </plugins>
  79. </build>
  80. <!--第三方maven私服-->
  81. <repositories>
  82. <repository>
  83. <id>nexus-aliyun</id>
  84. <name>Nexus aliyun</name>
  85. <url>http://maven.aliyun.com/nexus/content/groups/public</url>
  86. <releases>
  87. <enabled>true</enabled>
  88. </releases>
  89. <snapshots>
  90. <enabled>false</enabled>
  91. </snapshots>
  92. </repository>
  93. </repositories>

创建Gateway Module

Sentinel与Gateway整合实现微服务的集群流控 - 图2

导入依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alibaba.cloud</groupId>
  7. <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>com.alibaba.cloud</groupId>
  11. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>com.alibaba.cloud</groupId>
  15. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.cloud</groupId>
  19. <artifactId>spring-cloud-starter-gateway</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-actuator</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.cloud</groupId>
  27. <artifactId>spring-cloud-starter-openfeign</artifactId>
  28. </dependency>

修改application.yml

  1. spring:
  2. application:
  3. # 应用名称
  4. name: sentinel-gateway
  5. cloud:
  6. nacos:
  7. discovery:
  8. server-addr: localhost:8848
  9. sentinel:
  10. transport:
  11. dashboard: localhost:8080
  12. gateway:
  13. discovery:
  14. locator:
  15. enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
  16. routes:
  17. - id: MICRO_SERVICE # 路由id,建议配合服务名
  18. uri: lb://MICRO-SERVICE #匹配路由名
  19. predicates:
  20. - Path=/test/** # 断言,路径相匹配的进行路由
  21. server:
  22. port: 9527
  23. # 目前无效
  24. management:
  25. endpoints:
  26. web:
  27. exposure:
  28. include: "*"
  29. # 配置日志级别,方别调试
  30. logging:
  31. level:
  32. org.springframework.cloud.gateway: debug

到这,gateway的配置结束,紧接着创建一个普通的微服务

Sentinel与Gateway整合实现微服务的集群流控 - 图3

修改pom.xml依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alibaba.cloud</groupId>
  7. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>com.alibaba.cloud</groupId>
  11. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-web</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-actuator</artifactId>
  20. </dependency>

修改application.yml

  1. server:
  2. port: 8401
  3. spring:
  4. application:
  5. name: MICRO-SERVICE
  6. cloud:
  7. nacos:
  8. discovery:
  9. server-addr: localhost:8848
  10. sentinel:
  11. transport:
  12. dashboard: localhost:8080
  13. port: 8719
  14. management:
  15. endpoints:
  16. web:
  17. exposure:
  18. include: "*"

编写Controller,模拟业务请求

  1. @RestController
  2. @RequestMapping("/test")
  3. public class FlowLimitController {
  4. @GetMapping("/flowLimit")
  5. public String flowLimitTest() {
  6. return "flowLimitTest";
  7. }
  8. }

至此,基础测试环境搭建完毕,下面进行流控的测试

测试前提

  1. 启动Nacos服务注册中心
  2. 启动Sentinel-DashBoard

启动程序

如看到如下的情况,则证明,测试环境已经搭建完毕,下面可以进行网关的集群测试

Sentinel与Gateway整合实现微服务的集群流控 - 图4

点击流控,进行流控规则的配置

Sentinel与Gateway整合实现微服务的集群流控 - 图5

流控规则解释

如下图的配置中,代表,针对 MICRO-SERVICE这个微服务的请求,流控的类型为QPS,每10秒中,只能通过10个请求,多余的请求,会直接快速失败,抛出BlockException
Sentinel与Gateway整合实现微服务的集群流控 - 图6
配置完成之后,可以在流控规则中,看到配置的规则列表
Sentinel与Gateway整合实现微服务的集群流控 - 图7

配置完成之后,可以进行测试

详见以下的gif,可以看到,当在10秒中,超过10次请求,将会 返回 Blocked by Sentinel: ParamFlowException,进行流控
Sentinel与Gateway整合实现微服务的集群流控 - 图8

至此,网关的集群流控,就已经配置结束,同一微服务的集群的流控已经生效

但是,进而发现一件事,当网关服务进行重启之后, 模拟宕机之后重启, 在此访问 http://localhost:9527/test/flowLimit

此时,Sentinel-DashBoard 中 网关服务的流控规则已经没了,因为,Sentinel默认是内存存储,当服务宕机之后,内存中的东西,就已经丢失了
这个就十分头痛,难道每次都得重新配置嘛!!! ,答案是,当然不是,Sentinel提供了一个maven依赖,可以将Sentinel的配置,存储到Nacos配置中心中,当服务启动时
从Nacos配置中心拉去流控规则,进行流控,其依赖为

  1. <dependency>
  2. <groupId>com.alibaba.csp</groupId>
  3. <artifactId>sentinel-datasource-nacos</artifactId>
  4. </dependency>

其通过此依赖,拉取规则的配置如下,修改application.yml

主要添加datasource那段配置,配置从nacos上拉取的文件名,所在组等信息

  1. spring:
  2. application:
  3. # 应用名称
  4. name: sentinel-gateway
  5. cloud:
  6. nacos:
  7. discovery:
  8. server-addr: localhost:8848
  9. sentinel:
  10. transport:
  11. dashboard: localhost:8080
  12. datasource:
  13. gw-flow:
  14. nacos:
  15. server-addr: localhost:8848
  16. dataId: ${spring.application.name}-gateway-flow
  17. groupId: SENTINEL_GROUP
  18. rule-type: gw-flow
  19. gw-api-group:
  20. nacos:
  21. server-addr: localhost:8848
  22. dataId: ${spring.application.name}-gateway-api
  23. groupId: SENTINEL_GROUP
  24. rule-type: gw-api-group

在Nacos配置中心中创建如下的配置

Sentinel与Gateway整合实现微服务的集群流控 - 图9

创建完成之后,重启网关,访问一下 接口

http://localhost:9527/test/flowLimit

访问完成之后,查看Sentinel-DashBoard,看流控规则是否生效

可以看到,从Nacos上的配置已经生效,如果不信,可以将Nacos上的配置中的count修改为一个奇怪的值,如下,修改为123,可以看到,流控规则已经生效
Sentinel与Gateway整合实现微服务的集群流控 - 图10

至此,Sentinel与Nacos的流控规则生效,与网关的整合也生效了