sentinel規(guī)則持久化

Sentinel數(shù)據(jù)源

Sentinel的數(shù)據(jù)源可以通過多種方式加載:json、xml文件;zookeeper;apollo;nacos;并且可以多種數(shù)據(jù)源同時使用。

擴展方式

動態(tài)數(shù)據(jù)源:DataSource`擴展常見的實現(xiàn)方式


拉模式

客戶端主動向某個規(guī)則管理中心定期輪詢拉取規(guī)則,這個規(guī)則中心可以是 RDBMS、文件,甚至是 VCS 等。這樣做的方式是簡單,缺點是無法及時獲取變更;

推模式

規(guī)則中心統(tǒng)一推送,客戶端通過注冊監(jiān)聽器的方式時刻監(jiān)聽變化,比如使用 Nacos、Zookeeper 等配置中心。這種方式有更好的實時性和一致性保證。


一:客戶端從Nacos讀取限流規(guī)則

Sentinel客戶端配置

1. 引入POM依賴

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.70</version>
</dependency>

2. 修改配置文件

默認sentinel控制臺推送到nacos的dataId定義為: ${spring.application.name}-flow-rules
server.port=8083
# 配置中心url
spring.application.name=order-server
#注冊中心地址
spring.cloud.nacos.server-addr=192.168.64.128:8848
#添加sentinel依賴后 暴露/actuator/sentinel端點
# 開啟健康檢查
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=ALWAYS
#打開/關閉掉對Spring MVC端點的保護
spring.cloud.sentinel.filter.enabled=false
#這里的 spring.cloud.sentinel.transport.port 端口配置會在應用對應的機器上啟動一個 Http Server,該 Server 會與 Sentinel 控制臺做交互。比如 Sentinel 控制臺添加了1個限流規(guī)則,會把規(guī)則數(shù)據(jù) push 給這個 Http Server 接收,Http Server 再將規(guī)則注冊到 Sentinel 中。
spring.cloud.sentinel.transport.port=8731
#指定sentinel控制臺的地址
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080

# 設置Sentinel Nacos數(shù)據(jù)源配置;其中ds是數(shù)據(jù)源名,可以自行隨意修改
# Nacos數(shù)據(jù)源地址(需要啟動一臺Nacos Server)
# nacos 地址
spring.cloud.sentinel.datasource.ds.nacos.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.sentinel.datasource.ds.nacos.dataId=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.ds.nacos.groupId=SENTINEL_GROUP
# 數(shù)據(jù)類型
spring.cloud.sentinel.datasource.ds3.nacos.data-type=json
# 規(guī)則類型
spring.cloud.sentinel.datasource.ds.nacos.rule-type=flow

3. 添加Nacos數(shù)據(jù)源配置類

@Configuration
public class DataSourceInitFunc {

    Logger logger = LoggerFactory.getLogger(DataSourceInitFunc.class);

    @Autowired
    private SentinelProperties sentinelProperties;

    @Bean
    public DataSourceInitFunc init() throws Exception {

        logger.info("[NacosSource初始化,從Nacos中獲取熔斷規(guī)則]");

        sentinelProperties.getDatasource().entrySet().stream().filter(map -> {
            return map.getValue().getNacos() != null;
        }).forEach(map -> {
            NacosDataSourceProperties nacos = map.getValue().getNacos();
            // 限流規(guī)則,需要Nacos的dataId中包含flow字符串
            if (nacos.getDataId().contains("flow")) {
                ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(nacos.getServerAddr(),
                        nacos.getGroupId(), nacos.getDataId(),
                        source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                        }));
                FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
            }

            // 降級規(guī)則,需要Nacos的dataId中包含degrade字符串
            if (nacos.getDataId().contains("degrade")) {
                ReadableDataSource<String, List<DegradeRule>> degradeRuleDataSource = new NacosDataSource<>(nacos.getServerAddr(),
                        nacos.getGroupId(), nacos.getDataId(),
                        source -> JSON.parseObject(source, new TypeReference<List<DegradeRule>>() {
                        }));
                DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
            }

        });
        return new DataSourceInitFunc();
    }
}

4. Nacos中添加熔斷規(guī)則

根據(jù)配置文件配置的 id是 應用名-flow-rules
image.png

備注:

規(guī)則文件可以是json文件;也可以是text文件
規(guī)則是將 createOrder 的資源進行限流 使用QPS 模式 限流閾值 1

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

5. 測試
訪問 http://localhost:8083/order/createorder/1 進行測試

image.png

這樣會自動從配置中心讀取配置信息不需要每次重啟都需要配置了


二:Sentinel控制臺 將熔斷規(guī)則推送到Nacos數(shù)據(jù)源。

控制臺改造主要是為規(guī)則實現(xiàn)

  1. DynamicRuleProvider:從Nacos上讀取配置
  2. DynamicRulePublisher:將規(guī)則推送到Nacos上

1.下載控制臺源碼
下載Sentinel控制臺:https://github.com/alibaba/Sentinel/releases

image.png


2.修改POM文件

將sentinel-datasource-nacos的 <scope>test</scope> 這一行注釋掉
<!-- for Nacos rule publisher sample -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <!--  <scope>test</scope>-->
</dependency>

3. 相關類修改

找到 sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos目錄,將整個目錄拷貝到 sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos

image.png

4.修改NacosConfig類

修改NacosConfig類,修改NacosIP地址
image.png

5. FlowControllerV1修改
自動注入provider和publisher

@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;

@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
image.png

修改rules接口,讀取nacos中的數(shù)據(jù)

@GetMapping("/rules")
   @AuthAction(PrivilegeType.READ_RULE)
   public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app) {

       if (StringUtil.isEmpty(app)) {
           return Result.ofFail(-1, "app can't be null or empty");
       }
       try {
           List<FlowRuleEntity> rules = ruleProvider.getRules(app);
           if (rules != null && !rules.isEmpty()) {
               for (FlowRuleEntity entity : rules) {
                   entity.setApp(app);
                   if (entity.getClusterConfig() != null && entity.getClusterConfig().getFlowId() != null) {
                       entity.setId(entity.getClusterConfig().getFlowId());
                   }
               }
           }
           rules = repository.saveAll(rules);
           return Result.ofSuccess(rules);
       } catch (Throwable throwable) {
           logger.error("Error when querying flow rules", throwable);
           return Result.ofThrowable(-1, throwable);
       }
   }
image.png

該類最后的publishRules方法修改如下

private CompletableFuture<Void> publishRules(String app, String ip, Integer port) {
    List<FlowRuleEntity> rules = repository.findAllByMachine(MachineInfo.of(app, ip, port));
    try {
        rulePublisher.publish(app, rules);
        logger.info("添加限流規(guī)則成功.....");
    } catch (Exception e) {
        e.printStackTrace();
        logger.info("添加限流規(guī)則失敗.....");
    }
    return sentinelApiClient.setFlowRuleOfMachineAsync(app, ip, port, rules);
}
image.png

測試

訪問http://localhost:8080/可以進入到控制臺界面,但是界面上沒有任何的客戶端

請求一次http://localhost:8083/order/createorder/1,等一會兒,刷新一下就可以看到客戶端了

image.png

添加流控規(guī)則


image.png

并刷新一下就可以看到我們添加的規(guī)則了


image.png

在nacos配置中心查看

我們發(fā)現(xiàn)配置已經(jīng)被推送到了nacos


image.png

重啟客戶端進行測試

重啟客戶端后發(fā)現(xiàn)我們的規(guī)則是生效的,并且修改規(guī)則后重啟客戶端規(guī)則也是生效的

訪問 http://localhost:8083/order/createorder/1 進行測試

image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容