SpringCloudAlibaba - Sentinel 的规则持久化

目录

  • 前言
  • 拉模式
    • 原理
    • 实现
  • 推模式
    • 原理
    • 实现
  • 项目源码

前言

记录下Sentinel规则持久化的实现


拉模式

原理

Sentinel推送规则给微服务,微服务把规则生成JSON文件缓存到本地,Sentinel客户端会用一个定时任务定时去读取这个JSON文件并将它更新到规则缓存里,即使重启微服务,依然会从本地文件读取规则,通过这样的方式实现规则持久化

SpringCloudAlibaba - Sentinel 的规则持久化_第1张图片


实现

  • SentinelDataSourceInit.java
import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
import com.alibaba.csp.sentinel.datasource.*;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 规则持久化 - 拉模式
 */
public class SentinelDataSourceInit implements InitFunc {
    @Override
    public void init() throws Exception {
        // 存放路径
        String ruleDir = System.getProperty("user.home") + "/sentinel/rules";
        String flowRulePath = ruleDir + "/flow-rule.json";
        String degradeRulePath = ruleDir + "/degrade-rule.json";
        String systemRulePath = ruleDir + "/system-rule.json";
        String authorityRulePath = ruleDir + "/authority-rule.json";
        String paramFlowRulePath = ruleDir + "/param-flow-rule.json";

        this.mkdirIfNotExits(ruleDir);
        this.createFileIfNotExits(flowRulePath);
        this.createFileIfNotExits(degradeRulePath);
        this.createFileIfNotExits(systemRulePath);
        this.createFileIfNotExits(authorityRulePath);
        this.createFileIfNotExits(paramFlowRulePath);

        // 流控规则
        ReadableDataSource> flowRuleRDS = new FileRefreshableDataSource<>(
                flowRulePath,
                flowRuleListParser
        );
        
        // 将可读数据源注册至FlowRuleManager
        // 这样当规则文件发生变化时,就会更新规则到内存
        FlowRuleManager.register2Property(flowRuleRDS.getProperty());
        WritableDataSource> flowRuleWDS = new FileWritableDataSource<>(
                flowRulePath,
                this::encodeJson
        );
        
        // 将可写数据源注册至transport模块的WritableDataSourceRegistry中
        // 这样收到控制台推送的规则时,Sentinel会先更新到内存,然后将规则写入到文件中
        WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);

        // 降级规则
        ReadableDataSource> degradeRuleRDS = new FileRefreshableDataSource<>(
                degradeRulePath,
                degradeRuleListParser
        );
        DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
        WritableDataSource> degradeRuleWDS = new FileWritableDataSource<>(
                degradeRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);

        // 系统规则
        ReadableDataSource> systemRuleRDS = new FileRefreshableDataSource<>(
                systemRulePath,
                systemRuleListParser
        );
        SystemRuleManager.register2Property(systemRuleRDS.getProperty());
        WritableDataSource> systemRuleWDS = new FileWritableDataSource<>(
                systemRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);

        // 授权规则
        ReadableDataSource> authorityRuleRDS = new FileRefreshableDataSource<>(
                authorityRulePath,
                authorityRuleListParser
        );
        AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
        WritableDataSource> authorityRuleWDS = new FileWritableDataSource<>(
                authorityRulePath,
                this::encodeJson
        );
        WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);

        // 热点参数规则
        ReadableDataSource> paramFlowRuleRDS = new FileRefreshableDataSource<>(
                paramFlowRulePath,
                paramFlowRuleListParser
        );
        ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
        WritableDataSource> paramFlowRuleWDS = new FileWritableDataSource<>(
                paramFlowRulePath,
                this::encodeJson
        );
        ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
    }

    private Converter> flowRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference>() {
            }
    );
    private Converter> degradeRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference>() {
            }
    );
    private Converter> systemRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference>() {
            }
    );

    private Converter> authorityRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference>() {
            }
    );

    private Converter> paramFlowRuleListParser = source -> JSON.parseObject(
            source,
            new TypeReference>() {
            }
    );

    private void mkdirIfNotExits(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    private void createFileIfNotExits(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            file.createNewFile();
        }
    }

    private  String encodeJson(T t) {
        return JSON.toJSONString(t);
    }
}
  • resources/META-INF/services目录下创建文件com.alibaba.csp.sentinel.init.InitFunc ,添加SentinelDataSourceInit的全路径
com.coisini.contentcenter.core.SentinelDataSourceInit
  • 启动项目配置一条流控规则

SpringCloudAlibaba - Sentinel 的规则持久化_第2张图片

  • 重启Sentinel控制台和微服务,访问接口(Sentinel是懒加载)查看规则,如果存在则证明配置成功

  • 规则文件存放如下:

SpringCloudAlibaba - Sentinel 的规则持久化_第3张图片


  • 内容如下:

SpringCloudAlibaba - Sentinel 的规则持久化_第4张图片


推模式

原理

Sentinel控制台将规则推送到NacosZookeeper等存储,微服务通过客户端连接NacosZookeeper就可以获取到Nacos上的规则,同时也会监听数据变更,如果规则发生变化,就更新Sentinel客户端的规则

SpringCloudAlibaba - Sentinel 的规则持久化_第5张图片


实现

参考博客:Alibaba Sentinel规则持久化-推模式


项目源码

  • GitHub: https://github.com/Maggieq8324/coisini-cloud-alibaba
  • Gitee: https://gitee.com/maggieq8324/coisini-cloud-alibaba

- End -
- 个人学习笔记 -
- 仅供参考 -

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