前面介绍过持久化但存在问题,属于客户端拉模式,nacos端新建规则,增大了工作量有没有客户端在页面点击就会保存在服务端呢?就是生产上常用的客户端推模式!
Alibaba Sentinel规则持久化-推模式-【基于Nacos】
一、推模式架构图
二、原理简述
-
控制台推送规则:
-
将规则推送到Nacos或其他远程配置中心
-
Sentinel客户端链接Nacos,获取规则配置;并监听Nacos配置变化,如发生变化,就更新本地缓存(从而让本地缓存总是和Nacos一致)
-
-
控制台监听Nacos配置变化,如发生变化就更新本地缓存(从而让控制台本地缓存总是和Nacos一致)
三、微服务改造
开源Dashboard存在的问题
开源的dashboard功能是很弱的,因为所有数据都是存在内存中的,客户端重启规则就丢失了,监控数据也是存近5分钟数据在
dashboard内存中,自己搭建玩玩是可以的,但是不能用于生产环境的,想要在生产环境大规模使用,需要对dashboard做定制化
改造,需要完成以下几点:
1.鉴权,可以接入公司内部sso系统
2.规则持久化 ---> apollo,nacos,consul,zk,redis等
3.监控数据持久化 ----> influxdb
4.监控大屏 ----> 开发监控页面嵌入内部系统 or Grafana
5.报警 ----> 收集sentinel-block.log日志实现报警
当然了,也可以直接用阿里云上Sentinel控制台,功能也是比较完备的,基本上能满足日常需求
新建一个项目
cloud-sentinel-dashboard
把alibaba源码 sentinel-dashboard 部分都拷进项目
项目结构如图所示
-
加依赖
-
<?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>cloud_alibaba_learn</artifactId> <groupId>com.liu.learn</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-sentinel-dashboard</artifactId> <packaging>jar</packaging> <dependencies> <dependency> <groupId>com.liu.learn</groupId> <artifactId>cloud_common_public</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-core</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-web-servlet</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-parameter-flow-control</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-api-gateway-adapter-common</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--undertow容器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpasyncclient</artifactId> <version>4.1.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore-nio</artifactId> <version>4.4.6</version> </dependency> <!-- for Nacos rule publisher sample --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <!--<scope>test</scope>--> </dependency> </dependencies> <build> <finalName>pig-sentinel-dashboard</finalName> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> <resource> <directory>src/main/webapp/</directory> <excludes> <exclude>resources/node_modules/**</exclude> </excludes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!--<plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <configuration> <skip>false</skip> </configuration> </plugin>--> </plugins> </build> </project>
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
-
添加配置
spring: cloud: sentinel: datasource: # 名称随意 flow: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-flow-rules groupId: SENTINEL_GROUP # 规则类型,取值见: # org.springframework.cloud.alibaba.sentinel.datasource.RuleType rule-type: flow degrade: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-degrade-rules groupId: SENTINEL_GROUP rule-type: degrade system: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-system-rules groupId: SENTINEL_GROUP rule-type: system authority: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-authority-rules groupId: SENTINEL_GROUP rule-type: authority param-flow: nacos: server-addr: localhost:8848 dataId: ${spring.application.name}-param-flow-rules groupId: SENTINEL_GROUP rule-type: param-flow
四、Sentinel控制台改造
找到
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
目录,将整个目录拷贝到sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
,如图:
-
修改
com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2
,找到@Autowired @Qualifier("flowRuleDefaultProvider") private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider; @Autowired @Qualifier("flowRuleDefaultPublisher") private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
修改为:
@Autowired @Qualifier("flowRuleNacosProvider") private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider; @Autowired @Qualifier("flowRuleNacosPublisher") private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
再模仿flow规则,源码只提供了flow规则,其他自己写。
其他规则修改与flow不同,其他类里面的的代码写法可以参考flow规则
例如授权规则:com.alibaba.csp.sentinel.dashboard.controller.AuthorityRuleController
需要手动添加如下代码:
@Autowired
@Qualifier("authorityRuleNacosProvider")
private DynamicRuleProvider<List<AuthorityRuleEntity>> ruleProvider;
@Autowired
@Qualifier("authorityRuleNacosPublisher")
private DynamicRulePublisher<List<AuthorityRuleEntity>> rulePublisher;
发布规则方法替换原有的发布方法:
// added by hankin
private void publishRules(String app) throws Exception {
List<AuthorityRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
// private boolean publishRules(String app, String ip, Integer port) {
// List<AuthorityRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
// return sentinelApiClient.setAuthorityRuleOfMachine(app, ip, port, rules);
// }
com.alibaba.csp.sentinel.dashboard.controller.AuthorityRuleController#apiQueryAllRulesForMachine
查询规则方法替换:
try {
// added by hankin 通过 AuthorityRuleNacosProvider获取授权规则
List<AuthorityRuleEntity> rules = ruleProvider.getRules(app);
// List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);
rules = repository.saveAll(rules);
return Result.ofSuccess(rules);
} catch (Throwable throwable) {
com.alibaba.csp.sentinel.dashboard.controller.AuthorityRuleController#apiAddAuthorityRule
然后在增删改方法里面更新对应的publishRules发布方法:
try {
entity = repository.save(entity);
// added by hankin
publishRules(entity.getApp());
} catch (Throwable throwable) {
修改的文件:
五、编译 & 启动
-
执行
mvn clean package -DskipTests
-
在项目的
target
目录找到sentinel-dashboard.jar
,执行java -jar sentinel-dashboard.jar
启动控制台。
六、测试
-
测试1:用Sentinel控制台【菜单栏的
流控规则 V1
】推送流控规则,规则会存储到Nacos;
-
测试2:直接在Nacos上修改流控规则,然后刷新Sentinel控制台,控制台上的显示也会被修改;
-
测试3:重启Sentinel控制台,并重启微服务;刷新控制台,可以发现规则依然存在。
七、推模式优缺点分析
-
优点
-
规则持久化
-
一致性好
-
性能优秀
-
-
改动多、并且麻烦
-
引入额外的依赖(Nacos)
八、参考文档
https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel