
Sentinel 是什么
Sentinel 是面向分布式服務(wù)架構(gòu)的輕量級(jí)流量控制組件,主要以流量為切入點(diǎn),從限流、流量整形、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來幫助您保障微服務(wù)的穩(wěn)定性。
2012年起步,主要功能是入口流量控制,在阿里內(nèi)部覆蓋了所有核心場(chǎng)景。2018年開源,發(fā)展至今已經(jīng)可以提供各種維度、各種角度的風(fēng)騷的流量控制功能。
Sentinel流量整形實(shí)際效果
在本地環(huán)境使用 ab 對(duì)喜茶 GO 小程序菜單接口進(jìn)行30線程并發(fā)壓測(cè)
整形前

整形后

對(duì)比流量整形前后,在服務(wù)提供同樣QPS處理能力的情況下,平均RT從整形前的493-1730ms穩(wěn)定到了468-599ms,cpu從80%降至50%,削峰填谷效果明顯。
先回顧下Hystrix
Hystrix的核心功能:
- 資源隔離
- 熔斷
- 降級(jí)
兩種資源隔離策略:
線程池(默認(rèn))
通過HystrixCommand為調(diào)用依賴的api分配定制化的線程池,請(qǐng)求與調(diào)用線程分離,既異步調(diào)用
信號(hào)量
通過HystrixCommand為調(diào)用依賴的api分配信號(hào)量,請(qǐng)求與調(diào)用使用相同線程,既同步調(diào)用




Sentinel與Hystrix的差異
Hystrix 的關(guān)注點(diǎn)在于以隔離和熔斷為主的容錯(cuò)機(jī)制,超時(shí)或被熔斷的調(diào)用將會(huì)快速失敗,并可以提供 fallback 機(jī)制。
而 Sentinel

他的側(cè)重點(diǎn)在于:
- 多樣化的流量控制
- 熔斷降級(jí)
- 系統(tǒng)負(fù)載保護(hù)
- 實(shí)時(shí)監(jiān)控和控制臺(tái)
在熔斷策略上,Hystrix的兩種資源隔離策略無法同時(shí)滿足:低開銷+靈活的超時(shí)控制,而Sentinel可以同時(shí)配置并發(fā)線程數(shù)控制+響應(yīng)時(shí)間超時(shí)熔斷

Sentinel 的核心概念
使用 Sentinel 來進(jìn)行資源保護(hù),主要分為幾個(gè)步驟:
- 定義資源
- 定義規(guī)則
- 檢驗(yàn)規(guī)則是否生效
資源
資源是 Sentinel 的關(guān)鍵概念。它可以是 Java 應(yīng)用程序中的任何內(nèi)容,例如,由應(yīng)用程序提供的服務(wù),或由應(yīng)用程序調(diào)用的其它應(yīng)用提供的服務(wù),甚至可以是一段代碼。在接下來的文檔中,我們都會(huì)用資源來描述代碼塊。
只要通過 Sentinel API 定義的代碼,就是資源,能夠被 Sentinel 保護(hù)起來。大部分情況下,可以使用方法簽名,URL,甚至服務(wù)名稱作為資源名來標(biāo)示資源。
規(guī)則
圍繞資源的實(shí)時(shí)狀態(tài)設(shè)定的規(guī)則,可以包括流量控制規(guī)則、熔斷降級(jí)規(guī)則以及系統(tǒng)保護(hù)規(guī)則,或是自定義規(guī)則。所有規(guī)則可以動(dòng)態(tài)實(shí)時(shí)調(diào)整。
流量控制規(guī)則(FlowRule)
兩種統(tǒng)計(jì)類型
并發(fā)線程數(shù)流量控制:并發(fā)線程數(shù)限流用于保護(hù)業(yè)務(wù)線程數(shù)不被耗盡。Sentinel 并發(fā)線程數(shù)限流不負(fù)責(zé)創(chuàng)建和管理線程池,而是簡單統(tǒng)計(jì)當(dāng)前請(qǐng)求上下文的線程數(shù)目,如果超出閾值,新的請(qǐng)求會(huì)被立即拒絕,效果類似于信號(hào)量隔離。
-
QPS流量控制:當(dāng) QPS 超過某個(gè)閾值的時(shí)候,則采取措施進(jìn)行流量控制。流量控制的效果包括以下幾種:
直接拒絕
默認(rèn)的流量控制方式,當(dāng)QPS超過任意規(guī)則的閾值后,新的請(qǐng)求就會(huì)被立即拒絕,拒絕方式為拋出FlowException。這種方式適用于對(duì)系統(tǒng)處理能力確切已知的情況下,比如通過壓測(cè)確定了系統(tǒng)的準(zhǔn)確水位時(shí)。冷啟動(dòng)(Warm Up)
當(dāng)系統(tǒng)長期處于低水位的情況下,當(dāng)流量突然增加時(shí),直接把系統(tǒng)拉升到高水位可能瞬間把系統(tǒng)壓垮。通過"冷啟動(dòng)",讓通過的流量緩慢增加,在一定時(shí)間內(nèi)逐漸增加到閾值上限,給冷系統(tǒng)一個(gè)預(yù)熱的時(shí)間,避免冷系統(tǒng)被壓垮。
通常冷啟動(dòng)的過程系統(tǒng)允許通過的 QPS 曲線如下圖所示:

- 勻速排隊(duì)(流量整形)
該方式會(huì)嚴(yán)格控制請(qǐng)求通過的間隔時(shí)間,也即是讓請(qǐng)求以均勻的速度通過,對(duì)應(yīng)的是漏桶算法。這種方式主要用于處理間隔性突發(fā)的流量,例如消息隊(duì)列。想象一下這樣的場(chǎng)景,在某一秒有大量的請(qǐng)求到來,而接下來的幾秒則處于空閑狀態(tài),我們希望系統(tǒng)能夠在接下來的空閑期間逐漸處理這些請(qǐng)求,而不是在第一秒直接拒絕多余的請(qǐng)求。
該方式的作用如下圖所示:

使用Sentinel的這種策略, 簡單點(diǎn)說, 就是使用一個(gè)時(shí)間段(比如20s的時(shí)間)處理某一瞬時(shí)產(chǎn)生的大量請(qǐng)求, 起到一個(gè)削峰填谷的作用, 從而充分利用系統(tǒng)的處理能力, 下圖能很形象的展示這種場(chǎng)景: X軸代表時(shí)間, Y軸代表系統(tǒng)處理的請(qǐng)求.

三種流控模式
-
根據(jù)調(diào)用方限流
default(直接模式):表示不區(qū)分調(diào)用者,來自任何調(diào)用者的請(qǐng)求都將進(jìn)行限流統(tǒng)計(jì)。如果這個(gè)資源名的調(diào)用總和超過了這條規(guī)則定義的閾值,則觸發(fā)限流。
{some_origin_name}:表示針對(duì)特定的調(diào)用者,只有來自這個(gè)調(diào)用者的請(qǐng)求才會(huì)進(jìn)行流量控制。例如 NodeA 配置了一條針對(duì)調(diào)用者caller1的規(guī)則,那么當(dāng)且僅當(dāng)來自 caller1 對(duì) NodeA 的請(qǐng)求才會(huì)觸發(fā)流量控制。
other:表示針對(duì)除 {some_origin_name} 以外的其余調(diào)用方的流量進(jìn)行流量控制。例如,資源NodeA配置了一條針對(duì)調(diào)用者 caller1 的限流規(guī)則,同時(shí)又配置了一條調(diào)用者為 other 的規(guī)則,那么任意來自非 caller1 對(duì) NodeA 的調(diào)用,都不能超過 other 這條規(guī)則定義的閾值。
同一個(gè)資源名可以配置多條規(guī)則,規(guī)則的生效順序?yàn)椋簕some_origin_name} > other > default
根據(jù)調(diào)用鏈路入口限流:鏈路限流
只限流指定的入口資源產(chǎn)生的流量。比如有A、B、C資源,調(diào)用鏈路為A->C,B->C,可以對(duì)C進(jìn)行鏈路限流,指定入口資源為A,那么A->C會(huì)被限流,B->C不會(huì)具有關(guān)系的資源流量控制:關(guān)聯(lián)流量控制
當(dāng)關(guān)聯(lián)的資源達(dá)到閥值,就限流自己。比如有A、B資源,設(shè)置A資源為B資源的關(guān)聯(lián)資源,則當(dāng)A超過閾值時(shí),B就被限流(A不會(huì)被限流)。常用于避免讀寫資源爭搶導(dǎo)致的性能損耗。
熔斷降級(jí)規(guī)則 (DegradeRule)
平均響應(yīng)時(shí)間
異常比例
異常數(shù)
系統(tǒng)保護(hù)規(guī)則 (SystemRule)
Sentinel 系統(tǒng)自適應(yīng)限流從整體維度對(duì)應(yīng)用入口流量進(jìn)行控制,結(jié)合應(yīng)用的 Load、CPU 使用率、總體平均 RT、入口 QPS 和并發(fā)線程數(shù)等幾個(gè)維度的監(jiān)控指標(biāo),通過自適應(yīng)的流控策略,讓系統(tǒng)的入口流量和系統(tǒng)的負(fù)載達(dá)到一個(gè)平衡,讓系統(tǒng)盡可能跑在最大吞吐量的同時(shí)保證系統(tǒng)整體的穩(wěn)定性。
訪問控制規(guī)則 (AuthorityRule)
很多時(shí)候,我們需要根據(jù)調(diào)用方來限制資源是否通過,這時(shí)候可以使用 Sentinel 的訪問控制(黑白名單)的功能。黑白名單根據(jù)資源的請(qǐng)求來源(origin)限制資源是否通過,若配置白名單則只有請(qǐng)求來源位于白名單內(nèi)時(shí)才可通過;若配置黑名單則請(qǐng)求來源位于黑名單時(shí)不通過,其余的請(qǐng)求通過。
熱點(diǎn)規(guī)則 (ParamFlowRule)
何為熱點(diǎn)?熱點(diǎn)即經(jīng)常訪問的數(shù)據(jù)。很多時(shí)候我們希望統(tǒng)計(jì)某個(gè)熱點(diǎn)數(shù)據(jù)中訪問頻次最高的 Top K 數(shù)據(jù),并對(duì)其訪問進(jìn)行限制。比如:
商品 ID 為參數(shù),統(tǒng)計(jì)一段時(shí)間內(nèi)最常購買的商品 ID 并進(jìn)行限制
用戶 ID 為參數(shù),針對(duì)一段時(shí)間內(nèi)頻繁訪問的用戶 ID 進(jìn)行限制
熱點(diǎn)參數(shù)限流會(huì)統(tǒng)計(jì)傳入?yún)?shù)中的熱點(diǎn)參數(shù),并根據(jù)配置的限流閾值與模式,對(duì)包含熱點(diǎn)參數(shù)的資源調(diào)用進(jìn)行限流。熱點(diǎn)參數(shù)限流可以看做是一種特殊的流量控制,僅對(duì)包含熱點(diǎn)參數(shù)的資源調(diào)用生效。
定制自己的持久化規(guī)則
提供了開放的接口,您可以通過實(shí)現(xiàn) DataSource 接口的方式,來自定義規(guī)則的存儲(chǔ)數(shù)據(jù)源。通常我們的建議有:
- 整合動(dòng)態(tài)配置系統(tǒng),如 ZooKeeper、Nacos、Apollo 等,動(dòng)態(tài)地實(shí)時(shí)刷新配置規(guī)則
- 結(jié)合 RDBMS、NoSQL、VCS 等來實(shí)現(xiàn)該規(guī)則
- 配合 Sentinel Dashboard 使用
Sentinel工作原理概覽
在 Sentinel 里面,所有的資源都對(duì)應(yīng)一個(gè)資源名稱(resourceName),每次資源調(diào)用都會(huì)創(chuàng)建一個(gè) Entry 對(duì)象。Entry 可以通過對(duì)主流框架的適配自動(dòng)創(chuàng)建,也可以通過注解的方式或調(diào)用 SphU API 顯式創(chuàng)建。Entry 創(chuàng)建的時(shí)候,同時(shí)也會(huì)創(chuàng)建一系列功能插槽(slot chain),這些插槽有不同的職責(zé),例如:
- NodeSelectorSlot 負(fù)責(zé)收集資源的路徑,并將這些資源的調(diào)用路徑,以樹狀結(jié)構(gòu)存儲(chǔ)起來,用于根據(jù)調(diào)用路徑來限流降級(jí);
- ClusterBuilderSlot 則用于存儲(chǔ)資源的統(tǒng)計(jì)信息以及調(diào)用者信息,例如該資源的 RT, QPS, thread count 等等,這些信息將用作為多維度限流,降級(jí)的依據(jù);
- StatisticSlot 則用于記錄、統(tǒng)計(jì)不同緯度的 runtime 指標(biāo)監(jiān)控信息;
- FlowSlot 則用于根據(jù)預(yù)設(shè)的限流規(guī)則以及前面 slot 統(tǒng)計(jì)的狀態(tài),來進(jìn)行流量控制;
- AuthoritySlot 則根據(jù)配置的黑白名單和調(diào)用來源信息,來做黑白名單控制;
- DegradeSlot 則通過統(tǒng)計(jì)信息以及預(yù)設(shè)的規(guī)則,來做熔斷降級(jí);
- SystemSlot 則通過系統(tǒng)的狀態(tài),例如 load1 等,來控制總的入口流量;
總體的框架如下:

Sentinel 將 ProcessorSlot 作為 SPI 接口進(jìn)行擴(kuò)展(1.7.2 版本以前 SlotChainBuilder 作為 SPI),使得 Slot Chain 具備了擴(kuò)展的能力。您可以自行加入自定義的 slot 并編排 slot 間的順序,從而可以給 Sentinel 添加自定義的功能。

如何使用Sentinel
wiki:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
Quick Start https://github.com/alibaba/Sentinel/wiki/%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97#%E6%9C%AC%E5%9C%B0-demo
Sentinel Demo集錦:https://github.com/alibaba/Sentinel/tree/master/sentinel-demo
Spring Cloud Alibaba Sentinel:https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel