sentinel动态规则和持久化

sentinel动态规则

前言

我们在Sentinel Dashboard中配置流控规则(限流策略)、熔断规则(熔断策略)、热点规则(热点数据限流规则)。这些规则是存储在内存中的,一旦被监控项目重启配置的规则会被清掉(可以修改为nacos、数据库等)。基于这种情况sentinel支持我们使用nacos、zk等组件配置规则。此处以nacos配置动态规则为例介绍一下

sentinel动态规则

nacos配置动态规则

引入依赖

xml 复制代码
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.9</version>
 </dependency>

修改yml文件配置sentinel去读nacos配置

yaml 复制代码
spring: 
  cloud:
    sentinel:
	     datasource:
        flow: # ✅ :流控规则(QPS/并发线程数限流)最常用
        #degrade: # ✅ 熔断降级规则(异常比例/慢调用/异常数熔断)重点必配
        #param-flow: # ✅ 热点参数限流规则(对接口参数限流,比如你的userId)重点必配
        #authority: # 黑白名单规则(按调用来源限流)
        #system: # 系统保护规则(全服务入口限流,保护服务器CPU/负载)
        #gateway-flow: # 网关限流规则(只有SpringCloud Gateway网关服务才需要,你的业务服务不用配)
          nacos:
            server-addr: 127.0.0.1:8848
            # 若Nacos开启鉴权,添加账号密码
            username: nacos
            password: nacos
            dataId: system-flow-rules
            groupId: DEFAULT_GROUP
            #sentinel 相关配置
            rule-type: flow # rule-type要和datasource下的配置保持一致
            data-type: json #配置规则是json格式 数组类型
          

nacos上添加规则

通过上述配置后,我们可以在nacos上新增、修改配置,配置会自动生效。

控制台变更规则推送方案

​ nacos配置动态规则后,但是只能在nacos上修改、新增规则,在控制台修改nacos的修改新增,不会同步到nacos配置上,所以需要做一些调整来支持控制台修改规则同步nacos。推荐有两种方式

方案 是否推荐 说明
1. 控制台当临时工具 重启即丢
2. 只用 Nacos,不用控制台改规则 最稳妥
3. 二次开发 Sentinel Dashboard ⭐⭐⭐⭐ 最主流
4. 自己写规则管理后台 ⭐⭐⭐ 架构型方案
5. 推模式(Push)改造 ⭐⭐ 成本高
模式 介绍
原始模式(Embedded) 规则硬编码至应用,存储于内存,无持久化, 变更需修改代码并重启应用,仅适用于本地测试、功能验证场景
Pull 拉模式 客户端主动定时轮询数据源(本地文件 / 数据库), 规则持久化存储,变更后需等待轮询间隔生效, 适合单机、轻量且对规则生效时效要求不高的场景
Push 推模式 规则存储于远程配置中心(Nacos/Apollo 等) 客户端与配置中心建立长连接并监听规则变更 服务端主动推送新规则至客户端 实时生效且集群规则强一致,是生产环境集群部署的首选方案

生产推荐使用push 推模式

1、sentinel控制台变更 保存并推送到nacos、zk等

2、服务通过nacos、zk等数据源动态获取到规则。

控制台变更规则推送实操

官网推荐使用改在Sentinel Dashboard源码方式支持,控制台修改规则同步到nacos中,改造步骤如下

其实sentinel 1.8及以上其在测试模块中已经帮我实现了相关nacos同步的demo,其引入了相关依赖(test作用域)、FlowRuleNacosProviderFlowRuleNacosProvider类,可以参考该逻辑进行处理

下载源码

sentinel源码路径 关注sentinel-dashboard模块

引入nacos依赖

xml 复制代码
<!-- for Nacos rule publisher sample -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <!-- 注释掉 -->
    <!--<scope>test</scope>-->
</dependency>

添加配置

yaml 复制代码
#nacos 配置
nacos.server-addr=127.0.0.1:8848
nacos.namespace=sentinel #不填写默认是public空间下
nacos.username=nacos
nacos.password=nacos

实现nacos规则发布和读取器

类名 作用与核心职责
FlowRuleNacosPublisher(核心类) 规则发布器,负责将控制台变更的流控规则推送到 Nacos 进行持久化
FlowRuleNacosProvider(核心类) 规则读取器,负责从 Nacos 读取流控规则并加载到控制台
NacosConfig Nacos 核心配置类 ,用于初始化 Nacos 客户端连接 (默认链接localhost,如果nacos不在本地,则需要改造)
NacosConfigUtil 常量工具类,定义 Nacos 配置的统一常量

参考test目录下的nacos相关类 编写(复制-完善)到java目录中rule/nacos中(没有目录新建)。

FlowRuleNacosProvider实现从nacos读取流控规则

java 复制代码
@Component("flowRuleNacosProvider")
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 {
        //从在application.properties配置的命名空间,dataId=app+"-flow-rules",
        //group ="SENTINEL_GROUP" 下读取流控规则
        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);
    }
}

FlowRuleNacosPublisher向nacos推送规则

java 复制代码
@Component("flowRuleNacosPublisher")
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;
        }
        //推送到我们在application.properties配置的命名空间下,dataId=app+"-flow-rules",
        //group ="SENTINEL_GROUP" 下
        configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
            NacosConfigUtil.GROUP_ID, converter.convert(rules));
    }
}

改造v2类型接口

其实在sentinel Dashboard中的客户端集群模式下是支持v2接口的进行规则发布器和读取的。替换类下com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2.java 中的Publisher/Provider依赖实现 使用我们Nacos实现

依赖默认是flowRuleDefaultProvider 、flowRuleDefaultPublisher(基于内存读取、通知) 改成flowRuleNacosProvider、flowRuleNacosPublisher(基于nacos读取、通知) ,改造好了后v2相关接口对于流控规则的新增,变更操作都会同步到nacos。

注意

**控制台只有在集群模式下才会走v2的相关接口(v2相关接口)=需要手动使用v2/flow 形式显示指定url来控制。如下:http://127.0.0.1:8081/#/dashboard/v2/flow/ruoyi-system。此处可以改造流控规则的前端页面指向,将原来的v1改成v2接口。

改造后sentinel-dashboard-nacos 代码

支持使用jar启动 传入nacos,命令如下:

复制代码
java \
-Dsentinel.nacos.serverAddr=生产Nacos地址:8848 \
-Dsentinel.nacos.username=生产账号 \
-Dsentinel.nacos.password=生产密码 \
-Dsentinel.nacos.namespace=生产命名空间ID \
-jar 你的项目.jar

默认会使用生产命名空间ID下的dataId={appName}-flow-rules的group=SENTINEL_GROUP文件下变更流控规则

改造控制单机模式接口

因为控制台默认是单机页面

参考v2接口,其在所有规则数据发生变化情况下,重新重内存规则中获取所有规则,发布到具体数据源(nacos、zk、内存等)

java 复制代码
private void publishRules(/*@NonNull*/ String app) throws Exception {
  //查找所有流控规则 
  List<FlowRuleEntity> rules = repository.findAllByApp(app);
  //数据发布(同步都具体实现 对接nacos就同步到nacos)
  rulePublisher.publish(app, rules);
}

可以仿照类似v2接口 在其所有流控规则的增删改修改后,都给其调用publishRules方法触发规则同步到v1

重新修改服务从nacos获取规则的配置

注意需要保证sentinel控制台推送规则到nacos的对应namespace、dataId、groupId 等都保持一致。

复制代码
spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848
            # 必须与控制台推送的namespace完全一致(默认是public)
            namespace: sentinel
            # 必须与控制台推送的dataId完全一致
            dataId: ${spring.application.name}-flow-flues
            # 必须与控制台推送的groupId完全一致
            groupId: SENTINEL_GROUP
            data-type: json
            rule-type: flow
相关推荐
liushangzaibeijing6 小时前
Sentinel组件学习使用
sentinel·限流·熔断·服务降级
我是一只小青蛙8886 小时前
分布式流量守卫者:Sentinel深度解析
分布式·sentinel
廋到被风吹走3 天前
【Spring】Spring Cloud Gateway 网关架构深度解析:路由、过滤器、限流与 Sentinel 集成
spring·架构·sentinel
xiaolyuh1234 天前
Alibaba Sentinel 全解析
系统架构·sentinel·限流
9***g6874 天前
SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则
spring cloud·gateway·sentinel
DKunYu6 天前
9.熔断和限流 - Alibaba Sentinel
spring cloud·微服务·sentinel
南屿欣风7 天前
Sentinel 资源异常处理优先级笔记
spring boot·笔记·sentinel
lllsure10 天前
Alibaba Sentinel
微服务·sentinel
梵得儿SHI11 天前
SpringCloud 核心组件精讲:Sentinel 熔断限流全攻略-流量控制、熔断降级、热点参数限流(含 Dashboard 部署 + 项目集成实操)
java·spring cloud·sentinel·熔断降级·热点参数限流·微服务流量控制