sentinel 是什么
Sentinel 是面向分布式服務架構的輕量級流量控制框架,主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度來幫助您保護服務的穩(wěn)定性。
sentinel 基本概念
資源
資源是 Sentinel 的關鍵概念。它可以是 Java 應用程序中的任何內容,例如,由應用程序提供的服務,或由應用程序調用的其它應用提供的服務,甚至可以是一段代碼
規(guī)則
圍繞資源的實時狀態(tài)設定的規(guī)則,可以包括流量控制規(guī)則、熔斷降級規(guī)則以及系統保護規(guī)則。
sentinel 功能和設計理念
流量控制
對系統來說,任意時間到來的請求往往是隨機不可控的,而系統的處理能力是有限的。我們需要根據系統的處理能力對流量進行控制。

sentinel 流量控制有一下幾個角度:
- 資源的調用關系,例如資源的調用鏈路,資源和資源之間的關系;
- 運行指標,例如 QPS、線程池、系統負載等;
- 控制的效果,例如直接限流、冷啟動、排隊等。
熔斷降級
在微服務中,由于調用關系的復雜性,如果調用鏈路中的某個資源出現了不穩(wěn)定,比如服務超時,會導致請求發(fā)生堆積,長時間占用系統資源,最終會導致其他正常服務也不可用,導致整個系統的雪崩。熔斷降級就是當調用鏈路中某個資源出現不穩(wěn)定,例如,表現為 timeout,異常比例升高的時候,則對這個資源的調用進行限制,并讓請求快速失敗。
sentinel 熔斷的兩種方式:
- 通過并發(fā)線程數進行限制
和資源池隔離的方法不同,Sentinel 通過限制資源并發(fā)線程的數量,來減少不穩(wěn)定資源對其它資源的影響。這樣不但沒有線程切換的損耗,也不需要您預先分配線程池的大小。當某個資源出現不穩(wěn)定的情況下,例如響應時間變長,對資源的直接影響就是會造成線程數的逐步堆積。當線程數在特定資源上堆積到一定的數量之后,對該資源的新請求就會被拒絕。堆積的線程完成任務后才開始繼續(xù)接收請求。 - 通過響應時間對資源進行降級
除了對并發(fā)線程數進行控制以外,Sentinel 還可以通過響應時間來快速降級不穩(wěn)定的資源。當依賴的資源出現響應時間過長后,所有對該資源的訪問都會被直接拒絕,直到過了指定的時間窗口之后才重新恢復。
系統負載保護
Sentinel 同時對系統的維度提供保護。防止雪崩,是系統防護中重要的一環(huán)。當系統負載較高的時候,如果還持續(xù)讓請求進入,可能會導致系統崩潰,無法響應。在集群環(huán)境下,網絡負載均衡會把本應這臺機器承載的流量轉發(fā)到其它的機器上去。如果這個時候其它的機器也處在一個邊緣狀態(tài)的時候,這個增加的流量就會導致這臺機器也崩潰,最后導致整個集群不可用。
針對這個情況,Sentinel 提供了對應的保護機制,讓系統的入口流量和系統的負載達到一個平衡,保證系統在能力范圍之內處理最多的請求。
sentinel 的使用
使用 Sentinel 來進行資源保護,主要分為兩個步驟:
1.定義資源
2.定義規(guī)則
定義資源
拋出異常的方式定義資源
Entry entry = null;
// 務必保證finally會被執(zhí)行
try {
// 資源名可使用任意有業(yè)務語義的字符串
entry = SphU.entry("自定義資源名");
/**
* 被保護的業(yè)務邏輯
*/
} catch (BlockException e1) {
// 資源訪問阻止,被限流或被降級
// 進行相應的處理操作
} finally {
if (entry != null) {
entry.exit();
}
}
返回布爾值方式定義資源
// 資源名可使用任意有業(yè)務語義的字符串
if (SphO.entry("自定義資源名")) {
// 務必保證finally會被執(zhí)行
try {
/**
* 被保護的業(yè)務邏輯
*/
} finally {
SphO.exit();
}
} else {
// 資源訪問阻止,被限流或被降級
// 進行相應的處理操作
}
注解方式定義資源
Sentinel 支持通過 @SentinelResource 注解定義資源并配置 blockHandler 和 fallback 函數。
規(guī)則定義
Sentinel 支持以下幾種規(guī)則:流量控制規(guī)則、熔斷降級規(guī)則、系統保護規(guī)則 以及 授權規(guī)則。
流量規(guī)則的定義
| 屬性 | 說明 | 默認值 |
|---|---|---|
| resource | 資源名,資源名是限流規(guī)則的作用對象 | |
| count | 限流閾值 | |
| grade | 限流閾值類型,是按照 QPS 還是線程數 | QPS 模式 |
| limitApp | 是否根據調用者來限流 | 否 |
| strategy | 判斷的根據是資源自身,還是根據其它資源 (refResource),還是根據鏈路入口 (refResource) | 根據資源本身 |
| controlBehavior | 發(fā)生攔截后的流量整形和控制策略(直接拒絕 / 排隊等待 / 慢啟動模式) | 直接拒絕 |
硬編碼的方式定義流量控制規(guī)則實例:
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule1 = new FlowRule();
rule1.setResource(KEY);
// set limit qps to 20
rule1.setCount(20);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule1.setLimitApp("default");
rules.add(rule1);
FlowRuleManager.loadRules(rules);
}
熔斷降級規(guī)則 (DegradeRule)
| 屬性 | 說明 | 默認值 |
|---|---|---|
| resource | 資源名,資源名是限流規(guī)則的作用對象 | |
| count | 熔斷閾值 | |
| grade | 降級模式,根據 RT 降級還是根據異常比例降級 | RT |
| timeWindow | 降級的時間 |
硬編碼的方式定義流量控制規(guī)則實例:
private static void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource(KEY);
// set threshold rt, 10 ms
rule.setCount(10);
rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
rule.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
系統保護規(guī)則 (SystemRule)
| 屬性 | 說明 | 默認值 |
|---|---|---|
| highestSystemLoad | 最大的 load1,參考值 | -1 (不生效) |
| avgRt | 所有入口流量的平均響應時間 | -1 (不生效) |
| grade | 降級模式,根據 RT 降級還是根據異常比例降級 | RT |
| maxThread | 入口流量的最大并發(fā)數 | -1 (不生效) |
用硬編碼的方式定義流量控制規(guī)則的實例:
private void initSystemProtectionRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
}