让sentinel-dashboard的流控配置持久化到nacos

简介: 让sentinel-dashboard的流控配置持久化到nacos


官网 git: https://github.com/alibaba/Sentinel

微服务可以将流控配置放在nacos中,但dashboard修改的规则不能持久化。

本文将dashboard中的修改同步到nacos中,dashboard监控流控仍然从微服务客户端读取。

微服务客户端重启后会从nacos中读取数据,实现持久化。

主要思路: dashboard修改配置的时候,将数据发布到nacos中。注意dashboard中的是xxRuleEntity,而客户端读取nacos的是xxRule.

master分支 目前为sentinel-1.8.0为例

下载源码,idea打开。

找到sentinel-dashboard这个项目

在该项目下的pom.xml文件中找到:

  <!-- for Nacos rule publisher sample -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <scope>test</scope>
    </dependency>

将test注释掉。

展开test->java->com.alibaba.csp.sentinel.dashboard->rule->nacos

复制到src->java->com.alibaba.csp.sentinel.dashboard

  1. 主要文件

NacosCofig 服务配置 及convert


@Configuration
public class NacosConfig {

@Value("${sentinel.datasource.nacos.server-addr:localhost:8848}")
private String serverAddr;

@Value("${sentinel.datasource.nacos.enable:false}")
private boolean enable;

@Bean
public FlowRuleConvert flowRuleEntityEncoder() {
    return new FlowRuleConvert();
}

@Bean
public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
    return s -> JSON.parseArray(s, FlowRuleEntity.class);
}

@Bean
public ParamFlowRuleConvert paramFlowRuleEntityEncoder() {
    return new ParamFlowRuleConvert();
}

@Bean
public Converter<String, List<ParamFlowRuleEntity>> paramFlowRuleEntityDecoder() {
    return s -> JSON.parseArray(s, ParamFlowRuleEntity.class);
}



@Bean
public DegradeRuleConvert degradeRuleEntityEncoder() {
    return new DegradeRuleConvert();
}

@Bean
public Converter<String, List<DegradeRuleEntity>> degradeRuleEntityDecoder() {
    return s -> JSON.parseArray(s, DegradeRuleEntity.class);
}

@Bean
public ConfigService nacosConfigService() throws Exception {
    return ConfigFactory.createConfigService(serverAddr);
}


public boolean isEnable() {
    return enable;
}

public void setEnable(boolean enable) {
    this.enable = enable;
}

}

默认配置 NacosConfigUtil

注意 GROUP_ID 、xx_DATA_ID_POSTFIX 需要微服务客户端的一致

public final class NacosConfigUtil {

// public static final String GROUP_ID = "SENTINEL_GROUP";

public static final String GROUP_ID = "DEFAULT_GROUP";

public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";
public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";

/**
 * cc for `cluster-client`
 */
public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
/**
 * cs for `cluster-server`
 */
public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";
public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";
public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";

private NacosConfigUtil() {}

}

FlowRuleNacosPublisher 规则发布

@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List> {

@Autowired
private ConfigService configService;
@Autowired
private FlowRuleConvert converter;

@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
    AssertUtil.notEmpty(app, "app name cannot be empty");
    if (rules == null) {
        return;
    }
    boolean success = configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
        NacosConfigUtil.GROUP_ID, converter.convert(rules));
    if(!success){
        throw new RuntimeException("publish to nacos fail");
    }
}

}
ParamFlowRuleNacosPublisher

@Component("paramFlowRuleNacosPublisher")
public class ParamFlowRuleNacosPublisher implements DynamicRulePublisher<List> {

@Autowired
private ConfigService configService;
@Autowired
private ParamFlowRuleConvert converter;

@Override
public void publish(String app, List<ParamFlowRuleEntity> rules) throws Exception {
    AssertUtil.notEmpty(app, "app name cannot be empty");
    if (rules == null) {
        return;
    }
    boolean success = configService.publishConfig(app + NacosConfigUtil.PARAM_FLOW_DATA_ID_POSTFIX,
        NacosConfigUtil.GROUP_ID, converter.convert(rules));
    if(!success){
        throw new RuntimeException("publish to nacos fail");
    }
}

}

DegradeRuleNacosPublisher

@Component("degradeRuleNacosPublisher")
public class DegradeRuleNacosPublisher implements DynamicRulePublisher<List> {

@Autowired
private ConfigService configService;
@Autowired
private DegradeRuleConvert converter;

@Override
public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
    AssertUtil.notEmpty(app, "app name cannot be empty");
    if (rules == null) {
        return;
    }
    boolean success = configService.publishConfig(app + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
        NacosConfigUtil.GROUP_ID, converter.convert(rules));

    if(!success){
        throw new RuntimeException("publish to nacos fail");
    }
}

}

  1. 转换类

FlowRuleConvert

public class FlowRuleConvert implements Converter<List, String> {

@Override
public String convert(List<FlowRuleEntity> flowRuleEntities) {
    if(flowRuleEntities==null){
        return null;
    }
    List<FlowRule> flowRules = new ArrayList<>();
    for (FlowRuleEntity entity : flowRuleEntities) {
        FlowRule rule = new FlowRule();
        rule.setLimitApp(entity.getLimitApp());
        rule.setResource(entity.getResource());
        if(entity.getGmtCreate()!=null){
            rule.setGrade(entity.getGrade());
        }
        if(entity.getCount()!=null){
            rule.setCount(entity.getCount());
        }
        if(entity.getStrategy()!=null){
            rule.setStrategy(entity.getStrategy());
        }
        rule.setRefResource(entity.getRefResource());
        if(entity.getControlBehavior()!=null){
            rule.setControlBehavior(entity.getControlBehavior());
        }
        if(entity.getWarmUpPeriodSec()!=null){
            rule.setWarmUpPeriodSec(entity.getWarmUpPeriodSec());
        }
        if(entity.getMaxQueueingTimeMs()!=null){
            rule.setMaxQueueingTimeMs(entity.getMaxQueueingTimeMs());
        }
        rule.setClusterMode(entity.isClusterMode());
        rule.setClusterConfig(entity.getClusterConfig());

        flowRules.add(rule);
    }
    return JSON.toJSONString(flowRules,true);
}

}

ParamFlowRuleConvert

DegradeRuleConvert

@Autowired
private NacosConfig nacosConfig;

@Autowired
private FlowRuleNacosPublisher flowRuleNacosPublisher;

/ 修改publish /
private CompletableFuture publishRules(String app, String ip, Integer port) throws Exception {

List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
if(nacosConfig.isEnable()){
    flowRuleNacosPublisher.publish(app,rules);
}
return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);

}

ParamFlowRuleController

@Autowired
private NacosConfig nacosConfig;

@Autowired
private ParamFlowRuleNacosPublisher paramFlowRuleNacosPublisher;

private CompletableFuture publishRules(String app, String ip, Integer port) throws Exception {

List<ParamFlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
if(nacosConfig.isEnable()){
    paramFlowRuleNacosPublisher.publish(app,rules);
}
return sentinelApiClient.setParamFlowRuleOfMachine(app, ip, port, rules);

}

DegradeController

@Autowired
private NacosConfig nacosConfig;

@Autowired
private DegradeRuleNacosPublisher degradeRuleNacosPublisher;

private boolean publishRules(String app, String ip, Integer port) {

List<DegradeRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
if(nacosConfig.isEnable()){
    try {
        degradeRuleNacosPublisher.publish(app,rules);
    } catch (Exception e) {
        logger.error("publishRules failed. ",e);
        return false;
    }
}
return sentinelApiClient.setDegradeRuleOfMachine(app, ip, port, rules);

}

  1. 配置文件

nacos 配置开关 默认false

sentinel.datasource.nacos.enable=true

nacos 地址 默认 localhost:8848

sentinel.datasource.nacos.server-addr=localhost:8848
5 微服务端示例

配置文件

server:
port: 8081
spring:
application:

name: sentinel-spring-cloud-nacos

cloud:

sentinel:
  transport:
    dashboard: localhost:8080
  eager: false
  # sentinel nacos
  datasource:
    ds-flow:
      nacos:
        server-addr: 192.168.116.128:8848
        dataId: ${spring.application.name}-flow-rules
        groupId: DEFAULT_GROUP
        dataType: json
        rule-type: flow
    ds-param:
      nacos:
        server-addr: 192.168.116.128:8848
        dataId: ${spring.application.name}-param-rules
        groupId: DEFAULT_GROUP
        dataType: json
        rule-type: param-flow
    ds-degrade:
      nacos:
        server-addr: 192.168.116.128:8848
        dataId: ${spring.application.name}-degrade-rules
        groupId: DEFAULT_GROUP
        dataType: json
        rule-type: degrade

SentinelResource

@RestController
@RequestMapping("/api/sentinel")
public class SentinelDemoController {

@SentinelResource(value = "helloSentinel",blockHandler = "blockHandler",blockHandlerClass = SentinelBlockUtil.class )
@GetMapping("/helloSentinel")
public Object helloSentinel(){
    return "hello sentinel. "+System.currentTimeMillis();
}


@SentinelResource(value = "helloSentinelParam",blockHandler = "oneParamBlockHandler",blockHandlerClass = SentinelBlockUtil.class)
@GetMapping("/helloSentinelParam")
public Object helloSentinelParam(String userId){
    String data = "hello helloSentinelParam. userId:"+userId+"  "+System.currentTimeMillis();
    return data;
}

}
源码:https://github.com/lvzhyt/Sentinel/tree/dashboard-nacos

dashboard-nacos 分支 sentinel-dashboard

微服务客户端示例 sentinel-demo-spring-cloud-nacos

相关文章
|
26天前
|
Dubbo 关系型数据库 MySQL
nacos常见问题之命名空间配置数据上线修改如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
92 1
|
26天前
|
存储 运维 监控
NACOS 配置中心和注册中心是分两个集群部署还是放在一个集群中
【2月更文挑战第33天】NACOS 配置中心和注册中心是分两个集群部署还是放在一个集群中
71 2
|
11天前
|
SpringCloudAlibaba Java Nacos
SpringCloud Alibaba微服务 -- Nacos使用以及注册中心和配置中心的应用(保姆级)
SpringCloud Alibaba微服务 -- Nacos使用以及注册中心和配置中心的应用(保姆级)
|
26天前
|
编解码 Java Nacos
nacos常见问题之密码加密配置如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
128 0
|
26天前
|
安全 前端开发 Nacos
nacos常见问题之配置注册的白名单如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
81 0
|
26天前
|
网络安全 Nacos 数据安全/隐私保护
nacos常见问题之配置内容不显示也修改不了如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
97 0
|
26天前
|
运维 Java Nacos
nacos常见问题之配置不生效不加载shared-configs 配置如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
76 0
|
1月前
|
Java Nacos Sentinel
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(九)Nacos+Sentinel+Seata
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(九)Nacos+Sentinel+Seata
185 0
|
1月前
|
SpringCloudAlibaba Dubbo 前端开发
【三】SpringCloud Alibaba之Nacos整合篇(作为配置中心)
【三】SpringCloud Alibaba之Nacos整合篇(作为配置中心)
225 0
|
1月前
|
SpringCloudAlibaba 负载均衡 Java
【二】SpringCloud Alibaba之Nacos整合篇(配置负载均衡)
【二】SpringCloud Alibaba之Nacos整合篇(配置负载均衡)
237 0