sentinel持久化

sentinel规则推送模式

原始模式

在sentinel源码中是不支持规则持久化的,一旦sentinel服务宕机,匹配的所有规则将彻底消失。在上篇博客中展示了sentinel的源码流程图,在sentinel dashboard新增一条流控规则(或者其他规则),通过http协议将规则信息发送到客户端,客户端通过socket接收到规则信息后,将信息交给流控规则管理器(AuthorityRuleManager)处理,它会出发流控规则监听器执行更新缓存中的流控规则信息(map缓存)。
sentinel持久化_第1张图片

故我们需要对其进行改造,改造的方案有两种:

  • 本地文件持久化(拉模式)
  • 配置中心持久化(推模式)

拉模式

在原始模式中对客户端在缓存更新时,同时将规则保存到本地文件进行持久化。
sentinel持久化_第2张图片

创建推模式改造工程,使用SPI机制将加载改造类FileDataSoutceInit。
sentinel持久化_第3张图片
FileDataSoutceInit:

public class FileDataSourceInit implements InitFunc {

    @Override
    public void init() throws Exception {
        // A fake path.
        String flowRuleDir = System.getProperty("user.home") + File.separator + "sentinel" + File.separator + "rules";
        String flowRuleFile = "flowRule.json";
        String flowRulePath = flowRuleDir + File.separator + flowRuleFile;
        ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(
            flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})
        );
        // Register to flow rule manager.
        FlowRuleManager.register2Property(ds.getProperty());

        WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);
        // Register to writable data source registry so that rules can be updated to file
        // when there are rules pushed from the Sentinel Dashboard.
        WritableDataSourceRegistry.registerFlowDataSource(wds);
    }

    private <T> String encodeJson(T t) {
        return JSON.toJSONString(t);
    }
}

FileRefreshableDataSource:每次更新规则时自动读取持久化文件更新到map缓存。
FileWritableDataSource:写数据源,将sentinel控制台发送过来的规则信息写到持久化文件中。在客户端的socket接收到规则信息后,更新缓存的时候也会将规则信息写入文件中持久化。
sentinel持久化_第4张图片

推模式

推模式是通过注册中心实现的,sentinel控制台——>配置中心——>Sentinel数据源——>sentinel
sentinel持久化_第5张图片

改造sentinel Dashboard

用户不仅可以通过sentinel控制台进行更新,也可以通过nacos配置中心进行更新,所以在sentinel控制台或nacos中修改规则后,都需要通知对方刷新最新的配置。

  • 引入依赖
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.4.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-api</artifactId>
    <version>1.4.2</version>
    <scope>compile</scope>
</dependency>
  • 实现Sentinel数据源
    获取nacos配置中心规则的读数据源,
@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 {
        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);
    }
}

发布nacos监听事件的写数据源,将规则信息写入nacos配置中心

@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;
        }
        configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
            NacosConfigUtil.GROUP_ID, converter.convert(rules));
    }
}
  • 修改sentinel控制台发布规则的控制器
    在sentinel控制台中更新规则的源码如下(以流控规则为例),源码是直接发布到微服务客户端,而现在修改为发布到nacos配置中心
    sentinel持久化_第6张图片
    获取规则列表的接口如下,将它修改从nacos配置中心中获取规则信息
    sentinel持久化_第7张图片

测试

改造完成后,重新打包dashboard:
sentinel持久化_第8张图片
如此便能将规则持久化到nacos,而且无论是更新nacos配置中心的规则还是sentinel控制台的规则,都会持久化并且通过nacos推送到微服务客户端。
在sentinel中创建限流规则配置,内容如下:
sentinel持久化_第9张图片
在sentinel-test-client的配置文件中新增配置

spring.cloud.sentinel.datasource.flow-rules.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.flow-rules.nacos.data-id=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.flow-rules.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.flow-rules.nacos.data-type=json
spring.cloud.sentinel.datasource.flow-rules.nacos.rule-type=flow

之后nacos中会自动生成入如下配置
sentinel持久化_第10张图片
连续访问即出现限流
sentinel持久化_第11张图片
并且重启sentinel控制台后,已经配置过的流控规则不会丢失。

你可能感兴趣的:(sentinel,java,spring,cloud)