Sentinel nacos spring cloud 持久化配置---分布式/微服务流量控制

文章目录

  • sentinel控制台安装
  • 目标
  • 实现代码地址
  • 版本说明
  • maven spring-cloud-starter-alibaba-sentinel依赖
  • yml文件
  • Nacos业务规则配置
  • 看源码配置规则
    • SentinelProperties 总配置加载
    • DataSourcePropertiesConfiguration 配置
    • 标准的nacos配置
    • 注册具体sentinel配置
  • 外传

sentinel控制台安装

下载地址:https://github.com/alibaba/Sentinel/releases

本次版本:1.8.6
上一篇文章已介绍

目标

我们先说目标,为各位看官节省不匹配的时间
0、使用sentinel流控中心
1、使用nacos做配置中心
5、使用spring-cloud-starter-alibaba-sentinel做持久化配置

实现代码地址

https://github.com/OrderDong/microservice-boot
分支:microservice-boot-1.0.5-sentinel
当然,用springboot sentinel starter 使用nacos配置也是一样效果,不过需要自己实现,另一篇文章有参考
Sentinel nacos spring cloud 持久化配置---分布式/微服务流量控制_第1张图片

版本说明

Dubbo :3.1.0
Springboot:2.3.1.RELEASE
sentinel:1.8.6
Nacos-config:0.2.10

maven spring-cloud-starter-alibaba-sentinel依赖

https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel/


<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
    <version>2021.1version>
dependency>

yml文件

配置nacos datasource时可能不会给提示,我们直接看源码怎么加载的

spring:
  application:
    name: sentinel
  cloud:
    sentinel:
      transport:
        dashboard: localhost:7080 # 配置Sentinel dashboard地址
        heartbeat-interval-ms: 500
        client-ip: localhost:8719 # 配置Sentinel api地址
      datasource:
        ds1:
          nacos: # 关注点,添加Nacos数据源配置
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-plat-server
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
            

Nacos业务规则配置

[
  {
      "resource": "sayHello",
      "limitApp": "default",
      "grade": 1,
      "count": 5, 
      "strategy": 0,
      "controlBehavior": 0,
      "clusterMode": false
  }
]

看源码配置规则

SentinelProperties 总配置加载

package com.alibaba.cloud.sentinel;

import com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties(
    prefix = "spring.cloud.sentinel"
)
@Validated
public class SentinelProperties {
    private boolean eager = false;
    private boolean enabled = true;
    private String blockPage;
    //重点是这个
    private Map<String, DataSourcePropertiesConfiguration> datasource;


DataSourcePropertiesConfiguration 配置

支持很多中分布式配置中间件,我们重点关注nacos

public class DataSourcePropertiesConfiguration {
    private FileDataSourceProperties file;
    private NacosDataSourceProperties nacos;
    private ZookeeperDataSourceProperties zk;
    private ApolloDataSourceProperties apollo;
    private RedisDataSourceProperties redis;
    private ConsulDataSourceProperties consul;

    public DataSourcePropertiesConfiguration() {
    }

    //-----省略-----

    @JsonIgnore
    public List<String> getValidField() {
        return (List)Arrays.stream(this.getClass().getDeclaredFields()).map((field) -> {
            try {
                return !ObjectUtils.isEmpty(field.get(this)) ? field.getName() : null;
            } catch (IllegalAccessException var3) {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    @JsonIgnore
    public AbstractDataSourceProperties getValidDataSourceProperties() {
        List<String> invalidFields = this.getValidField();
        if (invalidFields.size() == 1) {
            try {
                this.getClass().getDeclaredField((String)invalidFields.get(0)).setAccessible(true);
                return (AbstractDataSourceProperties)this.getClass().getDeclaredField((String)invalidFields.get(0)).get(this);
            } catch (IllegalAccessException var3) {
            } catch (NoSuchFieldException var4) {
            }
        }

        return null;
    }
}

标准的nacos配置

package com.alibaba.cloud.sentinel.datasource.config;

import com.alibaba.cloud.sentinel.datasource.factorybean.NacosDataSourceFactoryBean;
import javax.validation.constraints.NotEmpty;
import org.springframework.util.StringUtils;

public class NacosDataSourceProperties extends AbstractDataSourceProperties {
    private String serverAddr;
    private String username;
    private String password;
    @NotEmpty
    private String groupId = "DEFAULT_GROUP";
    @NotEmpty
    private String dataId;
    private String endpoint;
    private String namespace;
    private String accessKey;
    private String secretKey;

    public NacosDataSourceProperties() {
        super(NacosDataSourceFactoryBean.class.getName());
    }

    public void preCheck(String dataSourceName) {
        if (StringUtils.isEmpty(this.serverAddr)) {
            this.serverAddr = this.getEnv().getProperty("spring.cloud.sentinel.datasource.nacos.server-addr", "localhost:8848");
        }

    }

注册具体sentinel配置

我们直接看下AbstractDataSourceProperties抽象数据源配置


//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.alibaba.cloud.sentinel.datasource.config;

import com.alibaba.cloud.sentinel.datasource.RuleType;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.springframework.core.env.Environment;

public class AbstractDataSourceProperties {
    @NotEmpty
    private String dataType = "json";
    @NotNull
    private RuleType ruleType;
    private String converterClass;
    @JsonIgnore
    private final String factoryBeanName;
    @JsonIgnore
    private Environment env;

    public AbstractDataSourceProperties(String factoryBeanName) {
        this.factoryBeanName = factoryBeanName;
    }

    public String getDataType() {
        return this.dataType;
    }

    public void setDataType(String dataType) {
        this.dataType = dataType;
    }

    public RuleType getRuleType() {
        return this.ruleType;
    }

    public void setRuleType(RuleType ruleType) {
        this.ruleType = ruleType;
    }

    public String getConverterClass() {
        return this.converterClass;
    }

    public void setConverterClass(String converterClass) {
        this.converterClass = converterClass;
    }

    public String getFactoryBeanName() {
        return this.factoryBeanName;
    }

    protected Environment getEnv() {
        return this.env;
    }

    public void setEnv(Environment env) {
        this.env = env;
    }

    public void preCheck(String dataSourceName) {
    }

    public void postRegister(AbstractDataSource dataSource) {
        switch(this.getRuleType()) {
        case FLOW:
            FlowRuleManager.register2Property(dataSource.getProperty());
            break;
        case DEGRADE:
            DegradeRuleManager.register2Property(dataSource.getProperty());
            break;
        case PARAM_FLOW:
            ParamFlowRuleManager.register2Property(dataSource.getProperty());
            break;
        case SYSTEM:
            SystemRuleManager.register2Property(dataSource.getProperty());
            break;
        case AUTHORITY:
            AuthorityRuleManager.register2Property(dataSource.getProperty());
            break;
        case GW_FLOW:
            GatewayRuleManager.register2Property(dataSource.getProperty());
            break;
        case GW_API_GROUP:
            GatewayApiDefinitionManager.register2Property(dataSource.getProperty());
        }

    }
}

具体再向下跟代码吧。。在这不说了。。

外传

 原创不易,如若本文能够帮助到您的同学
 支持我:关注我+点赞+收藏⭐️
 留言:探讨问题,看到立马回复
 格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!

你可能感兴趣的:(sentinel,spring,cloud,分布式)