Sentinel的所有规则默认都是内存存储,项目重启后所有规则都会丢失。在生产环境下,我们必须确保这些规则的持久化,避免丢失。
规则是否能持久化,取决于规则管理模式,Sentinel支持三种规则管理模式:
简介来自官方文档-在生产环境中使用 Sentinel:https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel
如果不做任何修改,Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存中
:
这种做法的好处是简单,无依赖;坏处是应用重启规则就会消失,仅用于简单测试,不能用于生产环境。
pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport 的 WritableDataSourceRegistry 中
。
生产环境下一般更常用的是 push 模式的数据源。
对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel
,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-datasource-nacosartifactId>
dependency>
比如:定义资源的流控规则如下(参数含义查看文档):
官方文档-流量控制:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
[
{
"resource": "/flow/getOrderByUserId2",
"controlBehavior": 0,
"count": 3,
"grade": 1,
"limitApp": "default",
"strategy": 0
}
]
在 yml配置文件中添加 Sentinel的配置数据源信息。
SentinelProperties 内部提供了 TreeMap 类型的 datasource 属性(点击进去可查看数据源配置默认信息)用于配置数据源信息。
server:
port: 18084
servlet:
context-path: /app-user-sentinel
spring:
application:
name: app-user-sentinel #应用名称
#nacos注册中心地址
cloud:
nacos:
server-addr: 192.168.xxx.xxx:8848
discovery:
username: nacos
password: nacos
namespace: b4d0832b-a7b0-44c2-8ce5-1abe676a4736 # 必须使用命名空间id
# group: prod
#sentinel控制台地址
sentinel:
transport:
web-context-unify: false # 默认true 将调用链路收敛, 导致链路流控效果无效
# 添加sentinel的控制台地址
dashboard: localhost:17080
# 指定应用与 Sentinel控制台交互的端口,
# port: 8719
# sentienl 数据源配置
datasource:
nacos-flow-rule: # 自定义数据源名称
nacos:
server-addr: 192.168.xxx.xxx:8848
username: nacos
password: nacos
namespace: b4d0832b-a7b0-44c2-8ce5-1abe676a4736 # 必须使用命名空间id
dataId: app-user-sentinel-flow-controller-getOrderByUserId2-rule # Nacos创建的配置DataId
rule-type: flow # 规则类型
data‐type: json # 默认值json。可以不配置它
# sentinel暴露actuator端点。
management:
endpoints:
web:
exposure:
#可以访问 /actuator/sentinel进行查看Sentinel监控项
include: '*'
logging:
level:
root: debug #开启 debug
controller如下:
/**
* http://localhost:18084/app-user-sentinel/flow/getOrderByUserId2/5
*
* @param id
* @return
*/
@RequestMapping(value = "/getOrderByUserId2/{id}")
@SentinelResource(value = "/flow/getOrderByUserId2", blockHandler = "blockHandlerForGetOrderByUserId2", fallback = "fallbackForGetOrderByUserId2")
public R getOrderByUserId2(@PathVariable("id") Integer id) throws InterruptedException {
log.info("根据userId=" + id + "查询订单信息");
if(id == 20){
TimeUnit.SECONDS.sleep(id);
}
String url = "http://app-order/order/findOrderByUserId/" + id;
R result = restTemplate.getForObject(url, R.class);
return result;
}
public R blockHandlerForGetOrderByUserId2(Integer id, BlockException blockEx) {
log.info("BlockException。id={}, blockEx = {}", id, blockEx.getMessage());
return R.error(" getOrderByUserId2 方法被流控了。id=" + id);
}
public R fallbackForGetOrderByUserId2(Integer id, Throwable e) {
log.info("业务出异常了。ex = {}", e.getMessage());
return R.error(" getOrderByUserId2 业务出异常了。ex = " + e);
}
启动项目,随意访问一个接口,Sentinel控制台进行初始化之后,我们就在Sentinel控制台上看到了Nacos上的配置信息。
然后访问该流控接口,发现流控规则ok。
到此,Sentinel持久化依赖 采用 Nacos 作为规则配置数据源整合OK。
但是有个点需要注意:
如何将通过 Sentinel控制台修改的规则直接持久化到 Nacos配置中心?
– 求知若饥,虚心若愚。