自去年10月底發佈GA版本後,Sentinel在近期發佈了另外一個里程碑版本v1.4(最新的版本號是v1.4.1),加入了開發者關注的集羣流控功能。java
爲何要使用集羣流控呢?假設咱們但願給某個用戶限制調用某個 API 的總 QPS 爲 50,但機器數可能不少(好比有 100 臺)。這時候咱們很天然地就想到,找一個 server 來專門來統計總的調用量,其它的實例都與這臺 server 通訊來判斷是否能夠調用。這就是最基礎的集羣流控的方式。json
那麼這個 server 如何部署呢?最直觀的方式就是做爲獨立的 token server 進程啓動,獨立部署:app
另外一種就是嵌入模式(Embedded),即做爲內置的 token server 與服務在同一進程中啓動,無需單獨部署:ide
另外集羣流控還能夠解決流量不均勻致使整體限流效果不佳的問題。假設集羣中有 10 臺機器,咱們給每臺機器設置單機限流閾值爲 10 QPS,理想狀況下整個集羣的限流閾值就爲 100 QPS。不過實際狀況下流量到每臺機器可能會不均勻,會致使總量沒有到的狀況下某些機器就開始限流:spa
所以僅靠單機維度去限制的話會沒法精確地限制整體流量。而集羣流控能夠精確地控制整個集羣的調用總量,結合單機限流兜底,能夠更好地發揮流量控制的效果。3d
Sentinel 1.4.0 開始引入了集羣流控模塊,主要分爲兩個部分:Token Client 和 Token Server:code
Sentinel 集羣流控支持限流規則和熱點規則兩種規則。集羣流控支持兩種形式的閾值計算方式:cdn
Sentinel 集羣流控服務端支持獨立模式(Alone)以及嵌入模式(Embedded)。二者的優缺點對比:server
Sentinel 提供 API 來對 client / server 進行配置以及指定模式,可是機器多的時候不方便進行管理。通常咱們須要經過 Sentinel 控制檯的集羣流控管理功能來統一管理某個應用集羣下全部的 token server 和 token client,靈活進行分配。xml
配置是集羣流控中比較重要的一部分。Sentinel 集羣流控的配置主要包含幾部分:
集羣規則配置須要藉助動態規則源。以集羣流控規則爲例,對於客戶端,咱們能夠用以前的方式向 FlowRuleManager
註冊動態規則源。而對於 Token Server,咱們須要向集羣規則管理器 ClusterFlowRuleManager
註冊規則源。咱們推薦的方式是在應用端註冊動態規則源,而後在 Sentinel 控制檯直接推送規則到配置中心,即 push 模式:
以嵌入模式爲例,一個比較好的實踐是:結合流量分佈和實時負載狀況來在服務集羣中選取幾臺較爲空閒的機器做爲 Token Server,其它的機器做爲 Token Client,劃分紅幾組,分別歸屬各自的 Token Server 管理。最後組成一個映射表,相似於:
// ip: token server IP, port: token server port, clientSet: 所管轄的 token client 集合
[{"clientSet":["112.12.88.66@8729","112.12.88.67@8727"],"ip":"112.12.88.68","machineId":"112.12.88.68@8728","port":11111}]
複製代碼
而後像 Token Client / Token Server 通訊配置、集羣流控模式等配置源均可以監聽這個分配映射表對應的數據源,來解析本身的身份和相關通訊配置。當分配映射表變動時每臺機器對應的身份和配置也會實時變動,實時生效。Sentinel 1.4.1 改進了 Sentinel 控制檯集羣流控的管理頁面,能夠直接以應用維度來分配 Token Server。能夠參考本文後面的指引來使用。
其它的配置好比 Token Server 的命名空間集合(namespace set,用於指定該 Token Server 能夠爲哪些應用/分組服務)、最大容許的總 QPS 等,既能夠經過 Sentinel 預留的 HTTP API 來變動配置,也能夠經過註冊動態配置源來進行配置。
下面咱們來看一下如何快速使用集羣流控功能。接入集羣流控模塊的步驟以下:
(1)引入集羣流控依賴
這裏咱們以嵌入模式來運行 token server,即在應用集羣中指定某臺機器做爲 token server,其它的機器指定爲 token client。
首先咱們引入集羣流控相關依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-client-default</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-server-default</artifactId>
<version>1.4.1</version>
</dependency>
複製代碼
(2)配置動態規則源
要想使用集羣流控功能,咱們須要在應用端配置動態規則源,並經過 Sentinel 控制檯實時進行推送。流程以下所示:
以流控規則爲例,假設咱們使用 ZooKeeper 做爲配置中心,則能夠向客戶端 FlowRuleManager
註冊 ZooKeeper 動態規則源:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
複製代碼
另外咱們還須要針對 Token Server 註冊集羣規則數據源。因爲嵌入模式下 token server 和 client 能夠隨時變換,所以咱們只需在每一個實例都向集羣流控規則管理器 ClusterFlowRuleManager
註冊動態規則源便可。Token Server 抽象出了命名空間(namespace)的概念,能夠支持多個應用/服務,所以咱們須要註冊一個自動根據 namespace 建立動態規則源的生成器:
// Supplier 會根據 namespace 生成的動態規則源,類型爲 SentinelProperty<List<FlowRule>>,針對不一樣的 namespace 生成不一樣的規則源(監聽不一樣 namespace 的 path).
// 默認 namespace 爲應用名(project.name)
// ClusterFlowRuleManager 針對集羣限流規則,ClusterParamFlowRuleManager 針對集羣熱點規則,配置方式相似
ClusterFlowRuleManager.setPropertySupplier(namespace -> {
return new SomeDataSource(address, dataIdPrefix + namespace).getProperty();
});
複製代碼
(3)控制檯進行改造適配動態規則源
咱們只需簡單對 Sentinel 控制檯進行改造便可直接將流控規則推送至配置中心。從 Sentinel 1.4.0 開始,Sentinel 控制檯提供 DynamicRulePublisher
和 DynamicRuleProvider
接口用於實現應用維度的規則推送和拉取,並提供了 Nacos 推送的示例(位於 test 目錄下)。咱們只須要實現本身的 DynamicRulePublisher
和 DynamicRuleProvider
接口並在 FlowControllerV2
類中相應位置經過 @Qualifier
註解指定對應的 bean name 便可,相似於:
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
複製代碼
Sentinel 控制檯提供應用維度推送的頁面(/v2/flow
)。在上述配置完成後,咱們能夠在此頁面向配置中心推送規則:
(4)控制檯分配 Token Server
當上面的步驟都完成後,咱們就能夠在 Sentinel 控制檯的「集羣流控」 Token Server 列表頁面管理分配 token server 了。假設咱們啓動了三個應用實例,咱們選擇一個實例爲 token server,其它兩個爲 token client:
頁面上機器的顯示方式爲 ip@commandPort
,其中 commandPort
爲應用端暴露給 Sentinel 控制檯的端口。選擇好之後,點擊 保存 按鈕,刷新頁面便可以看到 token server 分配成功:
而且咱們能夠在頁面查看 token server 的鏈接狀況:
(5)配置規則,觀察效果
接下來咱們配置一條集羣限流規則,限制 com.alibaba.csp.sentinel.demo.cluster.app.service.DemoService:sayHello(java.lang.String)
資源的集羣總 QPS 爲 10,選中「是否集羣」選項,閾值模式選擇整體閾值:
模擬流量同時請求這三臺機器,過一段時間後觀察效果。能夠在監控頁面看到對應資源的集羣維度的總 QPS 穩定在 10:
集羣流控可以精確地控制整個集羣的 QPS,結合單機限流兜底,能夠更好地發揮流量控制的效果。還有更多的場景等待你們發掘,好比:
儘管集羣流控比較好用,但它不是萬能的,只有在確實有必要的場景下才推薦使用集羣流控。
另外若在生產環境使用集羣限流,管控端還須要關注如下的問題:
將來咱們還計劃實現集羣流控多語言版本的客戶端,並對接 Service Mesh,讓 Sentinel 集羣流控能夠在更多場景下使用。