Sentinel 发布里程碑版本,添加集群流控功能
為什么80%的碼農都做不了架構師?>>> ??
自去年10月底發(fā)布GA版本后,Sentinel在近期發(fā)布了另一個里程碑版本v1.4(最新的版本號是v1.4.1),加入了開發(fā)者關注的集群流控功能。
集群流控簡介
為什么要使用集群流控呢?假設我們希望給某個用戶限制調用某個 API 的總 QPS 為 50,但機器數(shù)可能很多(比如有 100 臺)。這時候我們很自然地就想到,找一個 server 來專門來統(tǒng)計總的調用量,其它的實例都與這臺 server 通信來判斷是否可以調用。這就是最基礎的集群流控的方式。
那么這個 server 如何部署呢?最直觀的方式就是作為獨立的 token server 進程啟動,獨立部署:
另一種就是嵌入模式(Embedded),即作為內置的 token server 與服務在同一進程中啟動,無需單獨部署:
另外集群流控還可以解決流量不均勻導致總體限流效果不佳的問題。假設集群中有 10 臺機器,我們給每臺機器設置單機限流閾值為 10 QPS,理想情況下整個集群的限流閾值就為 100 QPS。不過實際情況下流量到每臺機器可能會不均勻,會導致總量沒有到的情況下某些機器就開始限流:
因此僅靠單機維度去限制的話會無法精確地限制總體流量。而集群流控可以精確地控制整個集群的調用總量,結合單機限流兜底,可以更好地發(fā)揮流量控制的效果。
Sentinel 1.4.0 開始引入了集群流控模塊,主要分為兩個部分:Token Client 和 Token Server:
- Token Client 即集群流控客戶端,用于向所屬 Token Server 通信請求 token。集群限流服務端會返回給客戶端結果,決定是否限流。Sentinel 集群流控的通信底層采用 Netty 實現(xiàn)。
- Token Server 即集群流控服務端,處理來自 Token Client 的請求,根據(jù)配置的集群規(guī)則判斷是否應該發(fā)放 token(是否允許通過)。
Sentinel 集群流控支持限流規(guī)則和熱點規(guī)則兩種規(guī)則。集群流控支持兩種形式的閾值計算方式:
- 集群總體模式:即限制整個集群內的某個資源的總體 QPS 不超過此閾值。
- 單機均攤模式:單機均攤模式下配置的閾值等同于單機能夠承受的限額,Token Server 會根據(jù)連接數(shù)來計算總的閾值(比如獨立模式下有 3 個 client 連接到了 token server,然后配的單機均攤閾值為 10,則計算出的集群總量就為 30),按照計算出的總的閾值來進行限制。這種方式根據(jù)當前的連接數(shù)實時計算總的閾值,對于機器經(jīng)常進行變更的環(huán)境非常適合。
部署方式
Sentinel 集群流控服務端支持獨立模式(Alone)以及嵌入模式(Embedded)。兩者的優(yōu)缺點對比:
- 獨立模式作為獨立的 token server 進程啟動,獨立部署,隔離性好,但是需要額外的部署操作。獨立模式適合作為 Global Rate Limiter 給整個集群提供流控服務。
- 嵌入模式作為內置的 token server 嵌入到應用進程中。嵌入模式下集群中各個實例都是對等的,token server 和 client 可以隨時進行轉變,無需單獨部署,靈活性比較好。但缺點就是隔離性不佳,
需要限制 token server 的總 QPS,防止影響應用本身。嵌入模式適合某個應用集群內部的流控。
Sentinel 提供 API 來對 client / server 進行配置以及指定模式,但是機器多的時候不方便進行管理。一般我們需要通過 Sentinel 控制臺的集群流控管理功能來統(tǒng)一管理某個應用集群下所有的 token server 和 token client,靈活進行分配。
配置
配置是集群流控中比較重要的一部分。Sentinel 集群流控的配置主要包含幾部分:
集群規(guī)則配置
集群規(guī)則配置需要借助動態(tài)規(guī)則源。以集群流控規(guī)則為例,對于客戶端,我們可以用之前的方式向 FlowRuleManager 注冊動態(tài)規(guī)則源。而對于 Token Server,我們需要向集群規(guī)則管理器 ClusterFlowRuleManager 注冊規(guī)則源。我們推薦的方式是在應用端注冊動態(tài)規(guī)則源,然后在 Sentinel 控制臺直接推送規(guī)則到配置中心,即 push 模式:
Token Server / Client 的分配
以嵌入模式為例,一個比較好的實踐是:結合流量分布和實時負載情況來在服務集群中選取幾臺較為空閑的機器作為 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 通信配置、集群流控模式等配置源都可以監(jiān)聽這個分配映射表對應的數(shù)據(jù)源,來解析自己的身份和相關通信配置。當分配映射表變更時每臺機器對應的身份和配置也會實時變更,實時生效。Sentinel 1.4.1 改進了 Sentinel 控制臺集群流控的管理頁面,可以直接以應用維度來分配 Token Server。可以參考本文后面的指引來使用。
其它配置
其它的配置比如 Token Server 的命名空間集合(namespace set,用于指定該 Token Server 可以為哪些應用/分組服務)、最大允許的總 QPS 等,既可以通過 Sentinel 預留的 HTTP API 來變更配置,也可以通過注冊動態(tài)配置源來進行配置。
快速使用集群流控
下面我們來看一下如何快速使用集群流控功能。接入集群流控模塊的步驟如下:
(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)配置動態(tài)規(guī)則源
要想使用集群流控功能,我們需要在應用端配置動態(tài)規(guī)則源,并通過 Sentinel 控制臺實時進行推送。流程如下所示:
以流控規(guī)則為例,假設我們使用 ZooKeeper 作為配置中心,則可以向客戶端 FlowRuleManager 注冊 ZooKeeper 動態(tài)規(guī)則源:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})); FlowRuleManager.register2Property(flowRuleDataSource.getProperty());另外我們還需要針對 Token Server 注冊集群規(guī)則數(shù)據(jù)源。由于嵌入模式下 token server 和 client 可以隨時變換,因此我們只需在每個實例都向集群流控規(guī)則管理器 ClusterFlowRuleManager 注冊動態(tài)規(guī)則源即可。Token Server 抽象出了命名空間(namespace)的概念,可以支持多個應用/服務,因此我們需要注冊一個自動根據(jù) namespace 創(chuàng)建動態(tài)規(guī)則源的生成器:
// Supplier 會根據(jù) namespace 生成的動態(tài)規(guī)則源,類型為 SentinelProperty<List<FlowRule>>,針對不同的 namespace 生成不同的規(guī)則源(監(jiān)聽不同 namespace 的 path). // 默認 namespace 為應用名(project.name) // ClusterFlowRuleManager 針對集群限流規(guī)則,ClusterParamFlowRuleManager 針對集群熱點規(guī)則,配置方式類似 ClusterFlowRuleManager.setPropertySupplier(namespace -> {return new SomeDataSource(address, dataIdPrefix + namespace).getProperty(); });(3)控制臺進行改造適配動態(tài)規(guī)則源
我們只需簡單對 Sentinel 控制臺進行改造即可直接將流控規(guī)則推送至配置中心。從 Sentinel 1.4.0 開始,Sentinel 控制臺提供 DynamicRulePublisher 和 DynamicRuleProvider 接口用于實現(xiàn)應用維度的規(guī)則推送和拉取,并提供了 Nacos 推送的示例(位于 test 目錄下)。我們只需要實現(xiàn)自己的 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)。在上述配置完成后,我們可以在此頁面向配置中心推送規(guī)則:
(4)控制臺分配 Token Server
當上面的步驟都完成后,我們就可以在 Sentinel 控制臺的“集群流控” Token Server 列表頁面管理分配 token server 了。假設我們啟動了三個應用實例,我們選擇一個實例為 token server,其它兩個為 token client:
頁面上機器的顯示方式為 ip@commandPort,其中 commandPort 為應用端暴露給 Sentinel 控制臺的端口。選擇好以后,點擊 保存 按鈕,刷新頁面即可以看到 token server 分配成功:
并且我們可以在頁面查看 token server 的連接情況:
(5)配置規(guī)則,觀察效果
接下來我們配置一條集群限流規(guī)則,限制 com.alibaba.csp.sentinel.demo.cluster.app.service.DemoService:sayHello(java.lang.String) 資源的集群總 QPS 為 10,選中“是否集群”選項,閾值模式選擇總體閾值:
模擬流量同時請求這三臺機器,過一段時間后觀察效果。可以在監(jiān)控頁面看到對應資源的集群維度的總 QPS 穩(wěn)定在 10:
總結
集群流控能夠精確地控制整個集群的 QPS,結合單機限流兜底,可以更好地發(fā)揮流量控制的效果。還有更多的場景等待大家發(fā)掘,比如:
- 在 API Gateway 處統(tǒng)計某個 API 的總訪問量,并對某個 API 或服務的總 QPS 進行限制
- Service Mesh 中對服務間的調用進行全局流控
- 集群內對熱點商品的總訪問頻次進行限制
盡管集群流控比較好用,但它不是萬能的,只有在確實有必要的場景下才推薦使用集群流控。
另外若在生產環(huán)境使用集群限流,管控端還需要關注以下的問題:
- Token Server 自動管理(分配/選舉 Token Server)
- Token Server 高可用,在某個 server 不可用時自動 failover 到其它機器
未來我們還計劃實現(xiàn)集群流控多語言版本的客戶端,并對接 Service Mesh,讓 Sentinel 集群流控可以在更多場景下使用。?
作者: 中間件小哥
原文鏈接
本文為云棲社區(qū)原創(chuàng)內容,未經(jīng)允許不得轉載。
轉載于:https://my.oschina.net/yunqi/blog/3001808
總結
以上是生活随笔為你收集整理的Sentinel 发布里程碑版本,添加集群流控功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 途牛自营门市超500家 单笔订单交易额最
- 下一篇: 微信小程序星级评分和展示