springBoot整合 sentinel限流 nacos动态规则配置
版本说明:(被版本坑惨了)
有一个图可以参考
springboot:2.1.3.RELEASE 后来改成2.1.2.RELEASE 了 但应该都可以
nacos:本地安装的1.4.0
sentinel:1.7.1
对应的包也引入支持sentinel1.7.1的
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.1.RELEASE</version> </dependency>
首先讲一些遇到的坑点吧。
刚开始引入的这个包 就本地连接sentinel还是可以成功的 但后面连接nacos就会报错
仔细观察可以看到引入该包 下面的sentinel相关的版本是1.5.2 所以出现的问题可能和版本有关
<!--sentinel提供的一个微服务开发的起步依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>0.9.0.RELEASE</version> </dependency>
言归正传开始整合
1.首先创建springBoot项目
配置文件application.yml
#端口号
server:
port: 8089
#项目名称
spring:
application:
name: sentinel-demo
cloud:
#配置sentinel客户端,注册该项目进控制台里
sentinel:
eager: true
transport:
#配置Sentin dashboard地址
dashboard: localhost:8080
# 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
port: 8719
#nacos 从nacos拉取数据需要配置
datasource:
#名称随意
flow:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-flow-rules
groupId: SENTINEL_GROUP
rule-type: flow
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.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>springboot-sentinel-start</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-sentinel-start</name> <description>Sentinel for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- springBoot包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--sentinel的包--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.1.RELEASE</version> </dependency> <!--使用 Nacos 配置规则--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <version>1.7.1</version> </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> <exclusion> <artifactId>spring-core</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
然后启动nacos
配置完这些之后就可以从nacos拉去规则配置了
启动sentinel-dashboard
进入sentinel可以看到 nacos中的规则已经展现在页面上
但是呢
限制在nacos修改规则 sentinel 控制台可以更新,而在控制台修改了之后 nacos并不会同步,如果我们重启springBoot项目后规则还是会变成nacos上面的值。
所以我们要对sentinel-dashboard的源码进行修改。
首先下载sentinel源码 https://github.com/alibaba/Sentinel/tree/1.7.1
然后打开sentinel-dashboard项目
1.首先 将1处的nacos文件夹复制到2处的rule文件夹下面
2.修改FlowControllerV2中的 flowRuleDefaultProvider 改为flowRuleNacosProvider 、flowRuleDefaultPublisher改为 flowRuleNacosPublisher
3.修改 FlowServiceV1 为FlowServiceV2
4.修改sidebar.html
5.修改flow_v2.html
以上就大功告成了。
改完之后可以将sentinel-dashboard 打一个jar包
使用 mvn clean package 进行源码编译
码编译通过后在Sentinel-release/sentinel-dashboard/target 下产生 sentinel-dashboard.jar 的jar包
需要时启动就可以 java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard.jar
java -Dserver.port=8080 \ 指定端口号
-Dcsp.sentinel.dashboard.server=localhost:8080 \ 外部服务连接sentinel控制台地址
-jar -sentinel-dashboard.jar 启动控制台
然后访问就可以了
坑点:
当控制台重启后,在已有的规则上在添加 规则会出现覆盖之前规则的情况。
原因:
说明 每次重启之后再添加 都会从id为1 的开始覆盖,如果原来有id为1得规则 就会被覆盖掉。
解决方案:修改 InMemFlowRuleStore.java 相应得 nextId()方法都要加上对应的参数
@Autowired private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository; @Override protected long nextId(FlowRuleEntity entity) { if(ids.intValue()==0){//如果是重启后 且存在已有规则则赋值为最大id+1 if(!CollectionUtils.isEmpty( repository.findAllByApp(entity.getApp()))){ long maxId=repository.findAllByApp(entity.getApp()).stream().max(Comparator.comparingLong(FlowRuleEntity::getId)).get().getId(); ids.set(maxId); } } return ids.incrementAndGet(); }