## 一、前言
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!
## 二、架构

* 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下面。

并修改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`修改部分如下:

~~~
<li ui-sref-active="active" ng-if="!entry.isGateway">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则</a>
</li>
~~~
## 四、DashBoard打包部署

~~~
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>
~~~
配置文件:

~~~
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发布一个流控规则。

登录 Nacos 后台,配置管理->配置列表:

点击进入配置详情,配置内容如下:
~~~
[{
"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:是否为集群模式
- 文档简介
- 模块与代码分支说明
- dongbb-cloud项目核心架构
- 微服务架构进化论
- SpringBoot与Cloud选型兼容
- Spring Cloud组件的选型
- 单体应用拆分微服务
- 单体应用与微服务对比
- 微服务设计拆分原则
- 新建父工程及子模块框架
- 通用微服务初始化模块构建
- 持久层模块单独拆分
- 拆分rbac权限管理微服务
- Hello-microservice
- 构建eureka服务注册中心
- 向服务注册中心注册服务
- 第一个微服务调用
- 远程服务调用
- HttpClient远程服务调用
- RestTemplate远程服务调用
- RestTemplate多实例负载均衡
- Ribbon调用流程源码解析
- Ribbon负载均衡策略源码解析
- Ribbon重试机制与饥饿加载
- Ribbon自定义负载均衡策略
- Feign与OpenFeign
- Feign设计原理源码解析
- Feign请求压缩与超时等配置
- 服务注册与发现
- 白话服务注册与发现
- DiscoveryClient服务发现
- Eureka集群环境构建(linux)
- Eureka集群多网卡环境ip设置
- Eureka集群服务注册与安全认证
- Eureka自我保护与健康检查
- 主流服务注册中心对比(含nacos)
- zookeeper概念及功能简介
- zookeeper-linux集群安装
- zookeeper服务注册与发现
- consul概念及功能介绍
- consul-linux集群安装
- consul服务注册与发现
- 通用-auatator导致401问题
- 分布式配置中心-apollo
- 服务配置中心概念及使用场景
- apollo概念功能简介
- apollo架构详解
- apollo分布式部署之Portal
- apollo分布式部署之环境区分
- apollo项目权限管理实战
- apollo-java客户端基础
- apollo与SpringCloud服务集成
- apollo实例配置热更新
- apollo命名空间与集群
- apollo灰度发布(日志热更新为例)
- SpringCloudConfig配置中心
- config-git配置文件仓库
- config配置中心搭建与测试
- config客户端基础
- config配置安全认证
- config客户端配置刷新
- config配置中心高可用
- BUS消息总线
- bus消息总线简介
- docker安装rabbitMQ
- 基于rabbitMQ的消息总线
- bus实现批量配置刷新
- alibaba-nacos
- nacos介绍与单机部署
- nacos集群部署方式(linux)
- nacos服务注册与发现
- nacos服务注册中心详解
- nacos客户端配置加载
- nacos客户端配置刷新
- nacos服务配置隔离与共享
- nacos配置Beta发布
- 服务熔断降级hystrix
- 服务降级&熔断&限流
- Hystrix集成并实现服务熔断
- Jemter模拟触发服务熔断
- Hystrix服务降级fallback
- Hystrix结合Feign服务降级
- 远程服务调用异常传递的问题
- Hystrix-Feign异常拦截与处理
- Hystrix-DashBoard单服务监控
- Hystrix-dashboard集群监控
- 分布式系统流量卫兵sentinel
- sentinel简介与安装
- 客户端集成与实时监控
- 实战流控规则-QPS限流
- 实战流控规则-线程数限流
- 实战流控规则-关联限流
- 实战流控规则-链路限流
- 实战流控效果-WarmUp
- 实战流控效果-匀速排队
- BlockException处理
- 实战熔断降级-RT
- 实战熔断降级-异常数与比例
- DegradeException处理
- 注解与异常的归纳总结
- Feign降级及异常传递拦截
- 动态规则nacos集中存储
- 热点参数限流
- 系统自适应限流
- 微服务网关-GateWay
- 还有必要学习Zuul么?
- 简介与非阻塞异步IO模型
- GateWay概念与流程
- 新建一个GateWay项目
- 通用Predicate的使用
- 自定义PredicateFactory
- 编码方式构建静态路由
- Filter过滤器介绍与使用
- 自定义过滤器Filter
- 网关请求转发负载均衡
- 结合nacos实现动态路由配置
- 整合Sentinel实现资源限流
- 跨域访问配置
- 网关层面全局异常处理
- 微服务网关安全认证-JWT篇
- Gateway-JWT认证鉴权流程
- 登录认证JWT令牌颁发
- 全局过滤器实现JWT鉴权
- 微服务自身内部的权限管理