sentinel 持久化
1. 概述
在前面的关于Sentinel的使用中,可以发现,Sentinel-dashboard配置的规则,在我们的微服务以及控制台重启的时候就清空了,因为他是基于内存的.
所以我们有必要将规则配置进行持久化, Sentinel 为我们提供了多种方式,多种选择:

官方文档:https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel
而最推荐的方式为Push模式,
我们可以将规则配置到注册中心中,例如ZooKeeper, Nacos, Apollo等等,当我们的客户端去连接时,将配置信息实时推送到各个客户端,概念图如下:

下面以Nacos 为例
2. 以Nacos演示
首先我们观察一下,没有注册Nacos的情况
手动注册规则,并进行访问:
@RestController
@RequestMapping("test")
@Slf4j
public class TestController {
@Autowired
private TestService testService;
/**
* 加载此类后执行
*/
@PostConstruct
public void init() {
List<FlowRule> rules = new ArrayList<>();
//新建一个规则
FlowRule rule = new FlowRule();
//保护的资源
rule.setResource("HelloWorld");
//设置为QPS的规则类型
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//值为2,则表示每秒只能访问此资源两次
rule.setCount(2);
rules.add(rule);
//加载此资源
FlowRuleManager.loadRules(rules);
}
@GetMapping("testB")
@SentinelResource(value = "HelloWorld",blockHandler = "handler" ,blockHandlerClass = CustomerBlockHandler.class)
public void testA() {
System.out.println("业务代码执行完毕!");
}
}
打印如下
业务代码执行完毕!
业务代码执行完毕!
方法被流控
方法被流控
方法被流控
方法被流控
业务代码执行完毕!
业务代码执行完毕!
方法被流控
方法被流控
控制台流控规则显示如下

说明此时本地注册的流控规则生效
使用Nacos配置:
添加依赖(pom):
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
添加访问数据源配置(yaml):
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
port: 8719
datasource:
dsl: # 名称随意
nacos:
server-addr: 192.168.100.108:8848 # nacos地址
dataId: cloudalibaba-sentinel-service #nacos配置的dataId
groupId: DEFAULT_GROUP # nacos配置的groupId
data_type: json # 配置文件类型
rule-type: flow #规则类型
management:
endpoints:
web:
exposure:
include: "*"
此时我们再访问testB 接口,发现此方法已经无法被流控,并且 控制台也没有显示此流控规则了, 说明 我们从Nacos中拉取规则时, 将覆盖本地规则,此时 Nacos 我们还没有配置,则 此时流控为空
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!

在Nacos中添加流控配置:
配置如下,其中 DataId ,GroupId, 配置类型 ,要和客户端中配置的一致,此流控规则为 QPS 为1

[
{
"resource":"/retaLimit/byUrl", // 资源名
"limitApp":"default", //来源应用
"grade":1, //阈值类型,0 表示线程数,1表示QPS
"count":1, // 单机阈值
"strategy":0, // 流控模式, 0表示直接,1表示关联, 2表示链路
"controlBehavior":0, //流控效果, 0表示快速失败,1表示 Warm Up, 2表示排队等待
"clusterMode":false //是否集群
}
]
此时客户端不用重启, 将自动将新增的流控规则推送到此客户端中:

快速访问流控接口:
@GetMapping("testD")
@SentinelResource(value = "/retaLimit/byUrl",blockHandler = "handler" ,blockHandlerClass = CustomerBlockHandler.class)
public void testD() {
System.out.println("业务代码执行完毕!");
}
打印信息如下:
业务代码执行完毕!
业务代码执行完毕!
业务代码执行完毕!
方法被流控
方法被流控
方法被流控
方法被流控
业务代码执行完毕!
方法被流控
方法被流控
说明成功将流控规则从Nacos中拉取下来,并此时重启客户端后,流控规则仍然存在,实现持久化.
3. 改造Sentinel-dashboard
在上面的演示中, 我们发现此时的dashboard,仅仅只是变成查看 客户端 从Nacos中拉取下来的配置,并没有连接到Nacos中, 所以当我们从dashboard中添加规则时,并没有将规则持久化到Nacos中, 当我们重启客户端后,dashboard 新增的规则仍然消失,
但是如果我们每次新增规则,都要以这样新增 JSON的方式,又比较麻烦,所以我们可以将dashboard进行改造,使之新增规则时,同样将规则持久化到Nacos中
首先,需要将dashboard 的源码下载下来: https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard (源码下载较慢的话,可以私信或评论发你),并打开(本人下载的是1.8)
查看源码中,在controller包中,有几个特殊的Controller, 对应着页面中的各个规则的CRUD, 以FlowControllerV1 为例:

查看此类,有一个非常重要的字段:
@Autowired
private SentinelApiClient sentinelApiClient;
每个Controller 就是通过这个对象, 与Sentinel客户端进行Http交互, 将从页面上增加,删除的操作,通过调用对应的API 来操作对应的客户端;
例如保存规则的方法中:
private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {
List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);
}
调用了此对象的setFlowRuleOfMachineAsync 方法,一直点进去看,会发现最终发送了一个Http请求,
executeCommand(new HttpGet(urlBuilder.toString()));
那么其他方法,其他各种规则配置类都是一样, 这样一来, dashboard 将直接与客户端请求HTTP请求, 下面我们进行改造,使之 读取规则从Nacos中读取,保存也往Nacos中保存,.
开始改造:
在此源码中,其实已经为我们准备了关于此方面的示例,在test包中,

已经有了关于关联Nacos的示例, 其中 FlowRuleNacosProvider 类和FlowRuleNacosPublisher 类分别继承了DynamicRuleProvider接口 和 DynamicRulePublisher 接口, 实现了拉取 和推送的方法, 而这两个类则可以替换FlowControllerV1 类中sentinelApiClient字段, 将这四个类拷贝到 主包中,创建Nacos文件夹:

注册类时修Bean的id:
@Component("myFlowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<String, List<FlowRuleEntity>> converter;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
@Component("myFlowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<FlowRuleEntity>, String> converter;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
并修改NacosConfig 类, 将Nacos的地址改成自己的地址
@Configuration
public class NacosConfig {
@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 {
return ConfigFactory.createConfigService("192.168.100.108");
}
}
并将依赖中,关于nacos持久化的包,test标签注释:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!--<scope>test</scope>-->
</dependency>
此时,我们只需将所有controller包中的sentinelApiClient ,换成 对应的 Nacos对象即可,例如上面的保存流控规则:
@RestController
@RequestMapping(value = "/v1/flow")
public class FlowControllerV1 {
private final Logger logger = LoggerFactory.getLogger(FlowControllerV2.class);
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
@Autowired
@Qualifier("myFlowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("myFlowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
private void publishRules(/*@NonNull*/ String app) throws Exception {
List<FlowRuleEntity> rules = repository.findAllByApp(app);
rulePublisher.publish(app, rules);
}
}
此时,当我们再保存流控规则时,将调用rulePublisher的 publish 方法, 对Nacos进行保存,
但是不建议修改原生的版本,官方也给我们提供了示例,即v2 包中FlowControllerV2类,此时的接口为 "/v2/flow"
@RestController
@RequestMapping(value = "/v2/flow")
public class FlowControllerV2
建议将所有的controller拷贝一份v2版本, 下面就着官方的示例,看如何将页面上的 菜单也切换到v2的版本上
同样,对于前端, 也提供了Demo, 在resources/app/scripts/directives/sidebar/sidebar.html 中,修改流控规则的路由,
将
<li ui-sref-active="active" ng-if="!entry.isGateway">
<a ui-sref="dashboard.flowV1({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则</a>
</li>
修改为
<a ui-sref="dashboard.flow({app: entry.app})">
路由规则配置在app.js中:

那么此时,当点击流控规则按钮时,将跳转到 flow_v2.html中, 而这个html也是提供好的,调用的接口都是 "v2":
如图:当我们再次点击流控规则时,无论是保存还是获取,都将调用v2的版本,其他页面也以此类推

同时,对于客户端,也需要添加指定对应的 dataId 和 GroupId
datasource:
dsl:
nacos:
server-addr: 192.168.100.109:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data_type: json
rule-type: flow
flow: # 和 改造后的对应
nacos:
server-addr: 192.168.100.109:8848
dataId: ${spring.application.name}-flow-rules
groupId: SENTINEL_GROUP
data_type: json
rule-type: flow
上面的介绍中,仅仅只是以流控规则为例, 即FlowControllerV1, 同时,对于Nacos, 也就只创建了FlowRuleNacosProvider 和 FlowRuleNacosPublisher 类, 对于其他 的例如降级规则,系统规则等,都需创建 对应的Nacos替换类, 用于替换相应controller的
sentinelApiClient 字段, 同时前端页面也是一样.
还有更简单的方式,是直接使用阿里云提供的服务,具体使用,请自行百度或者查看官网:
https://github.com/alibaba/Sentinel/wiki/AHAS-Sentinel-控制台
sentinel 持久化的更多相关文章
- Spring Cloud Alibaba(11)---Sentinel+Nacos持久化
Sentinel+Nacos持久化 有关Sentinel之前有写过两篇 Spring Cloud Alibaba(9)---Sentinel概述 Spring Cloud Alibaba(10)--- ...
- 微服务架构 | 5.2 基于 Sentinel 的服务限流及熔断
目录 前言 1. Sentinel 基础知识 1.1 Sentinel 的特性 1.2 Sentinel 的组成 1.3 Sentinel 控制台上的 9 个功能 1.4 Sentinel 工作原理 ...
- Spring Cloud Alibaba组件之Sentinel
目录 一 引入Sentinel学习 二 Sentinel入门 三 搭建Sentinel Dashboard 四 Springboot项目接入Sentinel 五 接入限流埋点 六 限流配置 七 熔断降 ...
- spring cloud alibaba sentinel 运行及简单使用
1.官网 英文:https://github.com/alibaba/Sentinel 中文:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7 ...
- 肝了很久,冰河整理出这份4万字的SpringCloud与SpringCloudAlibaba学习笔记!!
写在前面 不少小伙伴让我整理下有关SpringCloud和SpringCloudAlibaba的知识点,经过3天的收集和整理,冰河整理出这份4万字的SpringCloud与SpringCloudAli ...
- [Spring-Cloud-Alibaba] Sentinel 规则持久化
在之前的练习中,只要应用重启,就需要重新配置,这样在我们实际的项目是非常不实用的,那么有没有办法把我们配置的规则保存下来呢?答案是YES,那么接下来,给大家来介绍如何将Sentinel规则持久化. D ...
- 阿里Sentinel控制台源码修改-对接Apollo规则持久化
改造背景 前面我们讲解了如何对接Apollo来持久化限流的规则,对接后可以直接通过Apollo的后台进行规则的修改,推送到各个客户端实时生效. 但还有一个问题就是Sentinel控制台没有对接Apol ...
- Sentinel Client: 整合Apollo规则持久化
在前面的学习过程中,Sentinel 的规则,也就是我们之前定义的限流规则,是通过代码的方式定义好的.这是初始化时需要做的事情,Sentinel 提供了基于API的方式修改规则: FlowRuleMa ...
- Spring Cloud Alibaba学习笔记(7) - Sentinel规则持久化及生产环境使用
Sentinel 控制台 需要具备下面几个特性: 规则管理及推送,集中管理和推送规则.sentinel-core 提供 API 和扩展接口来接收信息.开发者需要根据自己的环境,选取一个可靠的推送规则方 ...
- sentinel控制台监控数据持久化【InfluxDB】
根据官方wiki文档,sentinel控制台的实时监控数据,默认仅存储 5 分钟以内的数据.如需持久化,需要定制实现相关接口. https://github.com/alibaba/Sentinel/ ...
随机推荐
- 基于spring security创建基本项目框架
SpringBoot建项目步骤 建表 新建项目 (package name可以自定义,整个项目只能在该包下) 选择可能有到的依赖 (别忘了勾选SQL中的Mybatis Framework,创建项目 如 ...
- 使用boot.iso镜像安装Oracle Linux 8
本文记录使用boot.iso镜像安装Oracle Linux 8. 镜像下载 Oracle Linux 8 boot镜像可以从这里下载. 安装 Oracle Linux 8 boot镜像安装系统跟使用 ...
- 强化学习基础篇【1】:基础知识点、马尔科夫决策过程、蒙特卡洛策略梯度定理、REINFORCE 算法
强化学习基础篇[1]:基础知识点.马尔科夫决策过程.蒙特卡洛策略梯度定理.REINFORCE 算法 1.强化学习基础知识点 智能体(agent):智能体是强化学习算法的主体,它能够根据经验做出主观判断 ...
- 戴尔全球首款6K IPS Black显示器上市:配4K摄像头
戴尔的全球首款6K IPS Black显示器--U3224KB,目前已经上架,价格为3199.99美元(约合人民币22186元). 据介绍,这款显示器采用IPS Black面板,刷新率为60Hz,对比 ...
- T406696 『STA - R4』冰红茶 题解
题目链接:冰红茶 比较有意思的套路题(前提是接触过) 首先,一个最基本的线段树包含两种操作的板子要会,分别为区间赋值与区间加,同时维护区间最值.这个挺简单的,区间赋值优先级高于区间加,可以将区间加覆盖 ...
- CH9140,CH9141,CH9143异同点
9140:是一款蓝牙转串口芯片,芯片支持蓝牙主从一体模式或从机模式,支持蓝牙 BLE4.2.串口波特率最高 1Mbps,支持 MODEM 联络信号,蓝牙主从模式可以自动连接或绑定. 智能配对功能 当 ...
- .NET Core开发实战(第1课:课程介绍)--学习笔记
01 | 课程介绍 讲师介绍 肖伟宇,校宝在线架构师.SkyWalking .NET探针贡献者.NetCorePal组件库创建者 为什么要学习 .NET Core 微软大力支持推动 .Net 技术生态 ...
- 2023年多校联训NOIP层测试4+洛谷 8 月月赛 I & RiOI Round 2
2023年多校联训NOIP层测试4 爆零了 T1 幸运数字 \(0pts\) 首先考虑一个结论: \(4\) 的倍数一定满足最后两位能被 \(4\) 整除. 从 \(1\) 进行输入,方便处理.若枚举 ...
- JS实现一个布隆过滤器
之前专门聊过令牌桶算法,而类似的方案还有布隆过滤器.它一般用于高效地查找一个元素是否在一个集合中. 用js实现如下所示: class BloomFilter { constructor(size, h ...
- mktemp命令
mktemp命令 mktemp命令用于安全地创建一个临时文件或目录,并输出其名称,TEMPLATE在最后一个组件中必须至少包含3个连续的X,如果未指定TEMPLATE,则使用tmp.XXXXXXXXX ...