在之前的架构里边,想要在gateway网关里边使用阿里的开源技术,sentinel来做网关层面的限流。一方面,阿里开源的,扛过高并发,上过生产,放心使用。另一方面社区相对来说已经成熟。

 但是由于错误的评估,话费了非常多的时间,因为sentinel使用起来,并不是那么的容易。特别是用在gateway网关中,更是到处都是坑。

 

 

目前我已经实现

1. gateway整合sentinel ,也就是在网关层面,实现使用sentinel限流。限流包括针对客户端ip限流,针对热点参数限流,针对head的某个字段限流。

2. 在经过修改源码以后,能够实现将sentinel的限流规则从dashbord推送到nacos。

 

我的技术选用

 springboot 2.2.5


<version>2.2.5.RELEASE</version>


 springCloud  Hoxton.SR3


<spring-cloud.version>Hoxton.SR3</spring-cloud.version>


 springCloudAlibaba  2.2.1.RELEASE

<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>

 

gateway  利用了springCloudAlibaba去适配的版本

nacos 利用了springCloudAlibaba去适配的版本, nacous的职责有 :注册中心*(用于gateway根据服务名称准发)、服务的配制中心、sentinel限流规则持久化的承载中心

 

 

这篇文章的目的

帮助想要使用sentinel的人,合理的去避免一些坑,少走一些弯路。明确一点,我这个主要针对在gateway网关中使用sentinel。我会写出来一些例子,就是demo项目的全部代码。

不是和sentinel官方抬杠。写的真的不怎么样,我是一个喜欢以官方文档作为一手学习资料的人,但是看过这么多,唯独sentinel这个,实在是看不下去,到处都是坑。

 

先来聊聊sentinel中都有哪些坑

官方文档不完整

 sentinel的官方文档,真的敷衍的不行。如果不花点时间,真的不知道在搞什么,看着官方文档,绝对搞不出来个一二三来。没有注意事项,没有详细的文档。自己借助了挺多文章来解决问题的。我都会分享出来。

使用sentinel因为版本没选对,而导致sentinel限流不生效问题

  各种不生效问题,多半是因为选用版本造成的。sentinel的官方文档上,并没有告诉我们,我们具体应该使用哪个版本。这就导致了,网上、社区里,官方群里,到处都是问为什么我的sentinel不生效。sentinel支持了跟很多技术的整合,可能功能挺好,但是文档太寒酸了。我会在这篇文章里把能用的资料都分享出来,具体的问题,在哪里找资料,以及如何解决。

  我遇到的第一个问题,就是在gateway 中刚引入sentinel的时候,限流不生效。官方文档没有告诉我们,springboot的版本大于 2.2.0 小于 2.3.1的。这个官方文档上并没有说。如果超出这个范围就是不生效。这是在我怎么都不生效的时候,我重新创建项目重新引入依赖的时候发现的。看下边的截图。

使用sentinel 遇到的一些坑_spring

 

关于需要改源码才生上生产的问题

  sentinel官方版本,目前到1.8.2版本是不支持 持久化限流规则的。在官方文档上,告诉我们,这样不能上生产,想要上生产,必须改造源码。至于怎么改造,没有明说,官网的例子很难看懂。果然是做技术的都不喜欢写文档,感情官网是加班写的吧。不过毕竟是有收费版的,如果这个大家都能用了,谁还去用收费版呢!

 能够上生产的sentinel,必须是把限流规则持久化到例如 nacos,等文件中。我们希望在生产中,能够不重启网关服务,就能够进行修改流控规则。我们最想要在sentinel提供的dashbord控制台修改了限流规则,然后把这个规则推到nacos,然后由我们的网关客户端吗,把它加载到内存中,并且限流生效。我选用的是使用nacos来做持久化,源码也是针对nacos来改造的。其实也不是很难,抓住一个关键点,无非就是找到把限流规则加载到内存中的操作,替换成推送到nacos。始终都是围绕这个点来展开的,我会用一篇详细的文章来介绍,如何改源码。并负责能让你的流控生效,又能持久化到你的nacos中。

  而限流规则一共有这么几种方式:

  • 通过编写代码的方式(弊端就是,每次修改规则,都需要重启网关,但凡是线上项目,都不会每次都重启项目来更新限流规则);
  • 通过sentinel提供的dashbord控制台(官方实现的是基于内存的,重启项目,就会丢失,相当于是每次重启项目,都需要手动重新配制限流规则,小孩子过家家,都不会这样玩);
  • 或者引入第三方放数据源(支持nacos,文件,等。但是想要使用这个,都是需要自己实现的,需要改源码的。本身sentinel源码里边并不支持,只能通过改源码)。

 

如何解决问题

官方文档不完整

 关于这个问题,个人是时间。很难不去全部补上,我这里只能给一个可用的案例。我会提供两篇单独的文章补到这里。

一篇是 gateway + sentinel + nacos 的案例。

一篇是修改源码,让sentinel—gateway  支持推送限流规则到 nacos。

我会保证我写的案例,一步一步跟着做出来,能够跑通。不再踩坑!

 

 

使用sentinel因为版本没选对,而导致sentinel限流不生效问题

  sentinel如何选择和springboot适配的版本,如何选择和springCloud适配的版本,如何选择和 springCloudAlibaba适配的版本。在官网上没有,但是在 springCloudAlibaba里边提到了sentinel,这是官网地址:​​https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E​

使用sentinel 遇到的一些坑_限流_02

使用sentinel 遇到的一些坑_spring_03

 另外我在这里分享出来我gateway整合sentinel 的全部的pom。这个是我使用的,我可以保证百分百能用。替换成我的,还是不能用的话,绝对是其他地方的错误,不用担心是因为版本的问题。

<?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.angus</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>业务网关</description>


<!-- 如果想要使用我的依赖依赖的话,就从这里开始,复制我的替换你全部pom。另外我这个是改造了把限流规则持久化到nacos的依赖,
如果没有改造则不用引入 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<java.encoding>UTF-8</java.encoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
<hutool.version>5.4.3</hutool.version>
<fastjson.version>1.2.71</fastjson.version>
<lombok.version>1.18.8</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Cloud 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud 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>
</dependencies>
</dependencyManagement>


<dependencies>
<!-- 基于 spring cloud gateway 实现网关服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- 整合 nacos 服务注册发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-test</artifactId>
<scope>test</scope>
</dependency>

<!-- 这个也是用来连接客户端和sentinel服务端的。在这里说一下sentinl服务端是指,你下载了sentinel的dashbord后台的jar包,并启动了起来。
此时你的网关部分就叫客户端。真正执行限流的部分,是在网关实现的, 连上服务端,也只是为了获取限流规则。-->

<!-- <dependency>-->
<!-- <groupId>com.alibaba.csp</groupId>-->
<!-- <artifactId>sentinel-transport-simple-http</artifactId>-->
<!-- <version>1.7.1</version>-->
<!-- </dependency>-->

<!--这里边是包括了上边提到的,连接sentinel dashbord 后台的实现,为什么使用这个不使用上边的。
因为使用上边的不能在 yml配制 sentinel相关的内容。配制以后不生效。这也是导致sentinel不生效的原因,有的有察觉到是配制文件不生效-->
<!-- sentinel 和 alibaba结合 相关的依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- gateway网关相关的依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.8.1</version>
</dependency>

<!-- sentinel热点参数限流相关的依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-parameter-flow-control</artifactId>
<version>1.8.1</version>
</dependency>

<!-- sentinel限流规则持久化nacos用到的相关的依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</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>

 

关于需要改源码才生上生产的问题

 

让sentinel—gateway  支持推送限流规则到 nacos ,这里单独补充一个文章。