Spring Cloud Alibaba | Sentinel:分布式系統的流量防衛兵動態限流規則


Spring Cloud Alibaba | Sentinel:分布式系統的流量防衛兵動態限流規則

前面幾篇文章較為詳細的介紹了Sentinel的使用姿勢,還沒看過的小伙伴可以訪問以下鏈接查看:

但是依然無法滿足我們日常的生產需要,其中,非常重要的一點就是限流規則的配置是存在當前應用的內存中的,每次我們重啟應用以后,我們在Sentinel控制台中配置的規則就丟失了,下面,我們就介紹一下Sentinel規則持久化的方式。

Sentinel為我們提供了兩種方式對規則進行修改:

  • 通過 API 直接修改 (loadRules)
  • 通過 DataSource 適配不同數據源修改

loadRules() 方法只接受內存態的規則對象,但更多時候規則存儲在文件、數據庫或者配置中心當中。DataSource 接口給我們提供了對接任意配置源的能力。相比直接通過 API 修改規則,實現 DataSource 接口是更加可靠的做法。

DataSource 擴展常見的實現方式有:

  • 拉模式:客戶端主動向某個規則管理中心定期輪詢拉取規則,這個規則中心可以是 RDBMS、文件,甚至是 VCS 等。這樣做的方式是簡單,缺點是無法及時獲取變更;
  • 推模式:規則中心統一推送,客戶端通過注冊監聽器的方式時刻監聽變化,比如使用 Nacos、Zookeeper 等配置中心。這種方式有更好的實時性和一致性保證。

Sentinel 目前支持以下數據源擴展:

  • Pull-based: 文件、Consul (since 1.7.0)
  • Push-based: ZooKeeper, Redis, Nacos, Apollo

這里,我們重點介紹一下Sentinel基於Nacos實現動態規則。

1. Sentinel基於Nacos動態規則實戰

1.1 創建子工程sentinel_nacos

工程依賴pom.xml如下:

代碼清單:Alibaba/sentinel-springcloud-high/sentinel_nacos/pom.xml


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

1.2 配置文件application.yml如下:

代碼清單:Alibaba/sentinel-springcloud-high/sentinel_nacos/src/main/resources/application.yml


server:
  port: 10000
spring:
  application:
    name: spring-cloud-sentinel-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.44.129:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8720
      datasource:
        ds:
          nacos:
            server-addr: 192.168.44.129:8848
            dataId: spring-cloud-sentinel-nacos
            groupId: DEFAULT_GROUP
            rule-type: flow
            namespace: 8282c713-da90-486a-8438-2a5a212ef44f
  • spring.cloud.sentinel.transport.dashboard:Sentinel控制台的訪問地址。
  • spring.cloud.sentinel.datasource.ds.nacos.server-addr:nacos的訪問地址。
  • spring.cloud.sentinel.datasource.ds.nacos.dataId:nacos中存儲規則的groupId。
  • spring.cloud.sentinel.datasource.ds.nacos.groupId:nacos中存儲規則的dataId。
  • spring.cloud.sentinel.datasource.ds.nacos.rule-type:用來定義存儲的規則類型,不可為空。
  • spring.cloud.sentinel.datasource.ds.nacos.namespace:nacos中存儲規則的namespace。

由於版本迭代關系,本示例中的配置信息不一定適用於所有版本,可以通過分析DataSourcePropertiesConfigurationNacosDataSourcePropertiesAbstractDataSourceProperties這三個配置來得出具體配置內容,會更為准確。

例如,本示例中的配置來源於NacosDataSourcePropertiesAbstractDataSourceProperties

NacosDataSourceProperties源碼如下:

public class NacosDataSourceProperties extends AbstractDataSourceProperties {

	private String serverAddr;

	@NotEmpty
	private String groupId = "DEFAULT_GROUP";

	@NotEmpty
	private String dataId;

	private String endpoint;
	private String namespace;
	private String accessKey;
	private String secretKey;

    // 代碼省略...
}

AbstractDataSourceProperties源碼如下:

public class AbstractDataSourceProperties {

	@NotEmpty
	private String dataType = "json";
	@NotNull
	private RuleType ruleType;
	private String converterClass;
	@JsonIgnore
	private final String factoryBeanName;
	@JsonIgnore
	private Environment env;
}

筆者這里僅配置一個不可為空並且沒有默認值的ruleType,有關ruleType的取值可以查看com.alibaba.cloud.sentinel.datasource.RuleType,這是一個枚舉類型。

1.3 創建一個接口測試類HelloController.java如下:

代碼清單:Alibaba/sentinel-springcloud-high/sentinel_nacos/src/main/java/com/springcloud/sentinel_nacos/controller/HelloController.java


@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(HttpServletRequest request) {
        return "Hello, port is: " + request.getLocalPort();
    }
}

1.4 配置Nacos配置中心

配置內容如圖:

注意其中配置的Data ID和Group要和程序中配置的保持一致。格式選擇JSON,填入的內容如下:

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

可以看到上面配置規則是一個數組類型,數組中的每個對象是針對每一個保護資源的配置對象,每個對象中的屬性解釋如下:

  • resource:資源名,即限流規則的作用對象。
  • limitApp:流控針對的調用來源,若為 default 則不區分調用來源。
  • grade:限流閾值類型,QPS 或線程數模式,0代表根據並發數量來限流,1代表根據QPS來進行流量控制。
  • count:限流閾值
  • strategy:判斷的根據是資源自身,還是根據其它關聯資源 (refResource),還是根據鏈路入口
  • controlBehavior:流控效果(直接拒絕 / 排隊等待 / 慢啟動模式)
  • clusterMode:是否為集群模式

1.5 測試

正常啟動子工程,打開瀏覽器訪問幾次http://localhost:10000/hello ,速度快一些可以發現已經限流了,限流后頁面顯示如下:

Blocked by Sentinel (flow limiting)

正面限流配置成功,這時我們打開Sentinel控制台,看一下流量規則限制,已經有一條數據了,是我們在Nacos中配置的數據,如圖:

注意:

在Sentinel動態規則整合了Nacos以后,對於修改接口流量控制就有兩個地方了,一個是Sentinel的控制台,還有一個是Nacos的控制台。

但是要謹記,在當前版本中,在Sentinel控制台中修改了規則,將不會同步至Nacos的配置中心,而在Nacos中修改了配置規則,則會通過在客戶端的Listener來是同步Sentinel控制台。所以,在整合了Nacos做動態規則存儲后需要注意兩點:

  • Sentinel控制台中修改規則:僅存在於服務的內存中,不會修改Nacos中的配置值,重啟后恢復原來的值。
  • Nacos控制台中修改規則:服務的內存中規則會更新,Nacos中持久化規則也會更新,重啟后依然保持。

建議各位堵住最好在Nacos控制台做規則的修改操作,盡量避免直接在Sentinel控制台中直接做規則修改。

2. 示例代碼

Github-示例代碼

Gitee-示例代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM