栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Sentinel配置规则持久化至Nacos

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Sentinel配置规则持久化至Nacos

文中使用的nacos版本1.4.2、sentinel版本1.8.3

问题

当集成了Sentinel的客户端应用重启之后,在控制台配置的规则全部都没有了,如果需要上生产环境需要将规则配置进行持久化。下面就来实现Sentinel规则配置持久化。

添加Maven依赖

需要持久化至nacos就需要添加相关Maven依赖


    com.alibaba.cloud
    spring-cloud-alibaba-sentinel-datasource




    com.alibaba.csp
    sentinel-datasource-nacos

配置

默认 Nacos 适配的 dataId 和 groupId 约定如下:

groupId: SENTINEL_GROUP规则配置 dataId: {appName}-flow-rules,比如应用名为 appA,则 dataId 为 appA-flow-rules

spring:
	cloud:
		sentinel:
			datasource:
			  # 自定义命名
			  flow-rule:
			    # 支持多种持久化数据源:file、nacos、zk、apollo、redis、consul
			    nacos:
			      # naco服务地址
			      server-addr: localhost:8848
			      # 命名空间,根据环境配置
			      namespace: public
			      # 这里我做了一下细分,不同规则设置不同groupId
			      group-id: SENTINEL_FLOW_GROUP
			      # 仅支持JSON和XML类型
			      data-id: ${spring.application.name}-flow-rules.json
			      # 规则类型:flow、degrade、param-flow、system、authority
			      rule-type: flow
			      # nacos开启了认证需要配置username、password
			      # username: nacos
			      # password: nacos
			      
Nacos配置

[{
	"clusterMode": false,
	"controlBehavior": 0,
	"count": 5.0,
	"grade": 1,
	"limitApp": "default",
	"resource": "/sentinel/flow",
	"strategy": 0
}]

规则配置详细官方文档:https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html

配置完成后,重启项目可以看到规则配置依然存在。修改Nacos中的配置也可以实时同步至Sentinel控制台了。

Sentinel控制台添加的规则推送至Nacos

从上面看来配置的规则可以持久化了,Nacos配置中心修改的规则可能实时同步至Sentinel控制台。但是在控制台中新增、修改、删除规则是无法同步至Nacos配置中心。在控制台添加了一个规则,如果客户端重启,规则就会丢失。下面就来实现控制台添加规则并推送至Nacos。

根据官方文档所述:Sentinel 控制台提供 DynamicRulePublisher 和 DynamicRuleProvider 接口用于实现应用维度的规则推送和拉取。

添加Maven依赖

    com.alibaba.boot
    nacos-config-spring-boot-starter
    0.2.10

添加application.properties配置

groupId根据命名约束自定义命名。

# 配置nacos服务地址与命名空间,可根据环境配置命名空间
nacos.config.server-addr=localhost:8848
nacos.config.namespace=8b1673aa-38da-48c6-bc5a-6df956ed0956

# 配置nacos groupId,可以自定义groupId
# 跟上面一样按照不同规则设置不同groupId
sentinel.nacos.flow.group-id=SENTINEL_FLOW_GROUP
sentinel.nacos.degrade.group-id=SENTINEL_DEGRADE_GROUP
sentinel.nacos.auth.group-id=SENTINEL_AUTH_GROUP
sentinel.nacos.param.group-id=SENTINEL_PARAM_GROUP
sentinel.nacos.system.group-id=SENTINEL_SYSTEM_GROUP
自定义FlowRulePublisher推送,并实现DynamicRulePublisher接口
@Component
public class FlowRulePublisher implements DynamicRulePublisher> {

    private static final Logger LOG = LoggerFactory.getLogger(FlowRulePublisher.class);

    @Value("${sentinel.nacos.flow.group-id}")
    private String nacosFlowGroupId;

    @Autowired
    private NacosConfigProperties nacosConfigProperties;

    
    @Override
    public void publish(String app, List rules) throws Exception {
        if (StringUtil.isBlank(app)) {
            return;
        }
        if (rules == null) {
            return;
        }

        LOG.info("========> 流控规则推送 -> app: {} rules:{}", app, JSON.toJSonString(rules));

        List flowFules = rules.stream().map(data -> {
            FlowRuleEntity entity = new FlowRuleEntity();
            entity.setResource(data.getResource());
            entity.setCount(data.getCount());
            entity.setGrade(data.getGrade());
            entity.setLimitApp(data.getLimitApp());
            entity.setStrategy(data.getStrategy());
            entity.setControlBehavior(data.getControlBehavior());
            return entity;
        }).collect(Collectors.toList());

        
        String dataId = String.format("%s-flow-rules.json", app);

        HttpHandler.handler(flowFules, nacosConfigProperties, nacosFlowGroupId, dataId);
    }
}
HttpHandler类
public class HttpHandler {

    private static final Logger LOG = LoggerFactory.getLogger(HttpHandler.class);

    public static void handler(Object rules, NacosConfigProperties nacosConfigProperties, String groupId, String dataId) throws IOException {
        StringJoiner param = new StringJoiner("&");
        param.add(String.format("tenant=%s", nacosConfigProperties.getNamespace())); // Nacos 的命名空间ID字段
        param.add(String.format("dataId=%s", dataId));
        param.add(String.format("group=%s", groupId));
        param.add(String.format("content=%s", URLEncoder.encode(JSON.toJSonString(rules), "UTF-8")));
        param.add(String.format("type=%s", "json"));

        String url = String.format("http://%s/nacos/v1/cs/configs?%s", nacosConfigProperties.getServerAddr(), param.toString());
        HttpPost httpPost = new HttpPost(url);

        CloseableHttpClient httpclient = HttpClients.createDefault();

        CloseableHttpResponse response = httpclient.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) {
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            LOG.info("========> 发布成功:{}", result);
        } else {
            LOG.error("========> 发布失败:{}", response.toString());
        }
    }
}

实现在推送接口后,找到Sentinel规则配置的Controller,并添加推送逻辑。我这里改造的是FlowControllerV1。

添加依赖注入属性:

最后在Controller中找到publisherRules方法,添加推送方法调用就可以了。

Sentinel在规则变更后会给客户端发送一个请求,去同步规则配置。


下面在控制台添加规则,就会推送至Nacos配置中心了。至此Sentinel配置规则持久化至Nacos就完成了。


参考:
Nacos Open API 文档:https://nacos.io/zh-cn/docs/open-api.html
Sentinel github地址:https://github.com/alibaba/Sentinel/releases
Sentinel官方文档:
https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel
https://github.com/alibaba/Sentinel/wiki/Sentinel-控制台(集群流控管理)#规则配置

提供相关业务逻辑处理源码位置,有兴趣的童鞋可以看一看。

客户端处理Sentinel请求的源码位置:

jar: sentinel-transport-common-1.8.3.jar
package: com.alibaba.csp.sentinel.command.handler


nacos监听处理源码位置:

jar: sentinel-datasource-nacos-1.8.3.jar
package: com.alibaba.csp.sentinel.datasource.nacos

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/758777.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号