ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 一、前言 Sentinel 原生版本的规则管理通过API 将规则推送至客户端并直接更新到内存中,当客户端服务重启时限流规则及降级规则的配置就会消失。对于生产环境而言,这显然不能满足要求! 一般来说,规则的推送有下面三种模式: | 推送模式 | 说明 | 优点 | 缺点 | | --- | --- | --- | --- | | 原始模式 | API 将规则推送至客户端并直接更新到内存中,扩展写数据源([`WritableDataSource`](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)) | 简单,无任何依赖 | 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境 | | Pull 模式 | 扩展写数据源([`WritableDataSource`](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等 | 简单,无任何依赖;规则持久化 | 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。 | | **Push 模式** | 扩展读数据源([`ReadableDataSource`](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。**生产环境下一般采用 push 模式的数据源。** | 规则持久化;一致性;快速 | 需要引入引入第三方依赖,并进行小幅度的sentinel dashboard代码改造 | 下面我们就实现Push模式,采用远程配置中心的方式,首选阿里系的开源产品nacos! ## 二、架构 ![](https://img2018.cnblogs.com/blog/109211/201909/109211-20190920082535582-637767939.png) * Sentinel DashBoard控制台配置发布并推送到nacos配置中心 * 客户端通过监听事件从配置中心准实时获取流控规则。 > 目前sentinel的动态规则集中存储到nacos做的还很不完善。截止到2020年5月13日,sentinel只能将“限流规则”发布到nacos配置管理中心。并且web页面很不完整,有些按钮将配置可以发布到nacos,有些按钮不能将配置发布到nacos。所以本节内容暂时先学习一下即可,后续还会有新的进展。虽然官网上说这是生产上的使用方案,但是也只是未来在生产上的使用方案,笔者建议暂时最好不要用于生产! ## 三、Sentinel DashBoard控制台代码调整 原始的Sentinel DashBoard控制台是不能实现将规则配置推送到nacos配置管理中心的,所以我们需要对源代码进行一定程度的改造。首先我们去github获取源码! ~~~ git clone https://github.com/alibaba/Sentinel.git ~~~ 下载完成后用IDEA打开,或有一定的maven下载过程等待。然后找到sentinel-dashboard子模块。 * 修改sentinel-dashboard子模块的pom.xml,原来的`<scope>test</scope>`去掉: ~~~ <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <!--scope>test</scope--> </dependency> ~~~ * 把sentinel-dashboard子模块`src/test`下面的包`com.alibaba.csp.sentinel.dashboard.rule.nacos`拷贝到`src/main/java`对应的package下面。 ![](https://img.kancloud.cn/d8/b4/d8b4af1c87390d997edcc9d1e35692ca_509x779.png) 并修改NacosConfig 内容为如下代码: ~~~ /** * @author Eric Zhao * @since 1.4.0 */ @Configuration public class NacosConfig { //这里是新增的nacos server地址 @Value("${nacos.address}") private String address; @Bean public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() { return JSON::toJSONString; } @Bean public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() { return s -> JSON.parseArray(s, FlowRuleEntity.class); } @Bean public ConfigService nacosConfigService() throws Exception { //使用nacos server 地址 Properties properties = new Properties(); properties.put("serverAddr",address); return ConfigFactory.createConfigService(properties); } } ~~~ * sentinel-dashboard子模块的application.properties 配置引入 Nacos,指向nacos服务: ~~~ # nacos的访问地址 nacos.address=192.168.161.6:8848 ~~~ * 修改java源代码`com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2`指定对应的 Bean 开启 Nacos 适配。修改部分如下: ~~~ @Autowired @Qualifier("flowRuleNacosProvider") private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider; @Autowired @Qualifier("flowRuleNacosPublisher") private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher; ~~~ * 修改`sidebar.html`页面, 流控规则路由从`dashboard.flowV1`改成`dashboard.flow`修改部分如下: ![](https://img.kancloud.cn/fe/62/fe62ffe0b068fbfbfe426f8ec86f6443_420x281.png) ~~~ <li ui-sref-active="active" ng-if="!entry.isGateway"> <a ui-sref="dashboard.flow({app: entry.app})"> <i class="glyphicon glyphicon-filter"></i>&nbsp;&nbsp;流控规则</a> </li> ~~~ ## 四、DashBoard打包部署 ![](https://img.kancloud.cn/fb/41/fb4147f53adcaa40e8a20535fe69b273_400x307.png) ~~~ java -Dserver.port=8774 \ -Dcsp.sentinel.heartbeat.client.ip=192.168.161.3 \ -Dproject.name=sentinel-dashboard -jar \ sentinel-dashboard.jar ~~~ ## 五、微服务客户端配置 pom.xml 引入: ~~~ <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> ~~~ 配置文件: ![](https://img.kancloud.cn/7f/eb/7febeb54f75a4540f19128094dbc03bd_1039x213.png) ~~~ spring: application: name: aservice-rbac cloud: sentinel: datasource: ds1: nacos: serverAddr: 192.168.161.6:8848 dataId: ${spring.application.name}-flow-rule groupId: SENTINEL_GROUP dataType: json ruleType: flow ~~~ * `spring.cloud.sentinel.datasource.ds1.nacos.server-addr`,nacos的访问地址 * `spring.cloud.sentinel.datasource.ds1.nacos.dataId`,nacos中存储规则的dataId,对于dataId使用了`${spring.application.name}`变量,这样可以根据应用名来区分不同的规则配置 * `spring.cloud.sentinel.datasource.ds1.nacos.groupId`nacos中存储规则的groupId,分组名称叫什么不重要,重要的是统一、易理解。默认是SENTINEL\_GROUP,我们配置的也是默认的 * `spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow`表示该数据源存储的是“限流规则”。 ~~~ # nacos有这么多的配置分类,从笔者了解目前只支持flow类型同步到nacos private static final String FLOW_RULE_TYPE = "flow"; private static final String DEGRADE_RULE_TYPE = "degrade"; private static final String SYSTEM_RULE_TYPE = "system"; private static final String AUTHORITY_RULE_TYPE = "authority"; ~~~ ## 六、发布流控配置 如图所示,界面会多了一个回到单机页面的按钮。目前只有通过这个界面上的绿色边框发布的流控规则,才能同步到nacos。我们使用它在sentinel发布一个流控规则。 ![](https://img.kancloud.cn/5d/f8/5df83bce334439351be4c675deb7f577_813x205.png) 登录 Nacos 后台,配置管理->配置列表: ![](https://img.kancloud.cn/6b/16/6b16d65cd689e42cbcfb789318c8b646_1634x146.png) 点击进入配置详情,配置内容如下: ~~~ [{ "app": "aservice-rbac", "clusterConfig": { "fallbackToLocalWhenFail": true, "sampleCount": 10, "strategy": 0, "thresholdType": 0, "windowIntervalMs": 1000 }, "clusterMode": false, "controlBehavior": 0, "count": 1.0, "gmtCreate": 1589348141737, "gmtModified": 1589348141737, "grade": 1, "id": 10, "ip": "192.168.1.4", "limitApp": "default", "port": 8719, "resource": "sysuserPwdReset", "strategy": 0 }] ~~~ 可以看到上面配置规则是一个数组类型,数组中的每个对象是针对每一个保护资源的配置对象,每个对象中的属性解释如下: * resource:资源名,即限流规则的作用对象 * limitApp:流控针对的调用来源,若为 default 则不区分调用来源 * grade:限流阈值类型(QPS 或并发线程数);`0`代表根据并发数量来限流,`1`代表根据QPS来进行流量控制 * count:限流阈值 * strategy:调用关系限流策略 * controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队) * clusterMode:是否为集群模式