SpringCloud Alibaba (三):Sentinel 流量控制組件
Sentinel 是什么
Sentinel 基本概念
資源
資源是 Sentinel 的關鍵概念。它可以是 Java 應用程序中的任何內容,例如,由應用程序提供的服務,或由應用程序調用的其它應用提供的服務,甚至可以是一段代碼。
只要通過 Sentinel API 定義的代碼,就是資源,能夠被 Sentinel 保護起來。大部分情況下,可以使用方法簽名,URL,甚至服務名稱作為資源名來標示資源。
規則
圍繞資源的實時狀態設定的規則,可以包括流量控制規則、熔斷降級規則以及系統保護規則。所有規則可以動態實時調整。
規則的種類
Sentinel 的所有規則都可以在內存態中動態地查詢及修改,修改之后立即生效。同時 Sentinel 也提供相關 API,供您來定制自己的規則策略。
Sentinel 支持以下幾種規則:流量控制規則、熔斷降級規則、系統保護規則、來源訪問控制規則 和 熱點參數規則。
流量控制規則 (FlowRule)
流量規則的定義0
重要屬性:
| Field | 說明 | 默認值 |
|---|---|---|
| resource | 資源名,資源名是限流規則的作用對象 | |
| count | 限流閾值 | |
| grade | 限流閾值類型,QPS 或線程數模式 | QPS 模式 |
| limitApp | 流控針對的調用來源 | default,代表不區分調用來源 |
| strategy | 調用關系限流策略:直接、鏈路、關聯 | 根據資源本身(直接) |
| controlBehavior | 流控效果(直接拒絕 / 排隊等待 / 慢啟動模式),不支持按調用關系限流 | 直接拒絕 |
同一個資源可以同時有多個限流規則。
通過代碼定義流量控制規則
理解上面規則的定義之后,我們可以通過調用 FlowRuleManager.loadRules() 方法來用硬編碼的方式定義流量控制規則,比如:
private static void initFlowQpsRule() { List<FlowRule> rules = new ArrayList<>(); FlowRule rule1 = new FlowRule(); rule1.setResource(resource); // Set max qps to 20 rule1.setCount(20); rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); rule1.setLimitApp("default"); rules.add(rule1); FlowRuleManager.loadRules(rules); }
更多詳細內容可以參考 流量控制。
熔斷降級規則包含下面幾個重要的屬性:
| Field | 說明 | 默認值 |
|---|---|---|
| resource | 資源名,即限流規則的作用對象 | |
| count | 閾值 | |
| grade | 熔斷策略,支持秒級 RT/秒級異常比例/分鍾級異常數 | 秒級平均 RT |
| timeWindow | 降級的時間,單位為 s |
同一個資源可以同時有多個降級規則。
理解上面規則的定義之后,我們可以通過調用 DegradeRuleManager.loadRules() 方法來用硬編碼的方式定義流量控制規則。
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); }
更多詳情可以參考 熔斷降級。
系統保護規則 (SystemRule)
規則包含下面幾個重要的屬性:
| Field | 說明 | 默認值 |
|---|---|---|
load1 閾值,參考值 |
-1 (不生效) | |
| avgRt | -1 (不生效) | |
| maxThread | 入口流量的最大並發數 | -1 (不生效) |
| qps | 所有入口資源的 QPS | -1 (不生效) |
| highestCpuUsage | 當前系統的 CPU 使用率(0.0-1.0) | -1 (不生效) |
理解上面規則的定義之后,我們可以通過調用 SystemRuleManager.loadRules() 方法來用硬編碼的方式定義流量控制規則。
private void initSystemProtectionRule() { List<SystemRule> rules = new ArrayList<>(); SystemRule rule = new SystemRule(); rule.setHighestSystemLoad(10); rules.add(rule); SystemRuleManager.loadRules(rules); }
更多詳情可以參考 系統自適應保護。
訪問控制規則 (AuthorityRule)
很多時候,我們需要根據調用方來限制資源是否通過,這時候可以使用 Sentinel 的訪問控制(黑白名單)的功能。黑白名單根據資源的請求來源(origin)限制資源是否通過,若配置白名單則只有請求來源位於白名單內時才可通過;若配置黑名單則請求來源位於黑名單時不通過,其余的請求通過。
授權規則,即黑白名單規則(AuthorityRule)非常簡單,主要有以下配置項:
-
resource:資源名,即限流規則的作用對象 -
limitApp:對應的黑名單/白名單,不同 origin 用,分隔,如appA,appB -
strategy:限制模式,AUTHORITY_WHITE為白名單模式,AUTHORITY_BLACK為黑名單模式,默認為白名單模式
更多詳情可以參考 來源訪問控制。
熱點規則 (ParamFlowRule)
詳情可以參考 熱點參數限流。
Sentinel控制台
概述
Sentinel 提供一個輕量級的開源控制台,它提供機器發現以及健康情況管理、監控(單機和集群),規則管理和推送的功能。另外,鑒權在生產環境中也必不可少。這里,我們將會詳細講述如何通過簡單的步驟就可以使用這些功能。
接下來,我們將會逐一介紹如何整合 Sentinel 核心庫和 Dashboard,讓它發揮最大的作用。同時我們也在阿里雲上提供企業級的控制台:AHAS Sentinel 控制台,您只需要幾個簡單的步驟,就能最直觀地看到控制台如何實現這些功能。
Sentinel 控制台包含如下功能:
-
查看機器列表以及健康情況:收集 Sentinel 客戶端發送的心跳包,用於判斷機器是否在線。
-
監控 (單機和集群聚合):通過 Sentinel 客戶端暴露的監控 API,定期拉取並且聚合應用監控信息,最終可以實現秒級的實時監控。
-
規則管理和推送:統一管理推送規則。
-
鑒權:生產環境中鑒權非常重要。這里每個開發者需要根據自己的實際情況進行定制。
更詳細內容,訪問 https://github.com/alibaba/Sentinel/wiki
啟動Sentinel控制台
1.在Sentinel的github上下載 sentinel-dashboard.jar
https://github.com/alibaba/Sentinel/releases
2.在sentinel-dashboard.jar所在文件夾運行cmd,在cmd里運行以下啟動命令啟動sentinel-dashboard
java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar
3.訪問 localhost:8081,進入Sentinel控制台,默認用戶和密碼都是 sentinel

SpringCloud Alibaba 整合 Sentinel
Sentinel 可以簡單的分為 Sentinel 核心庫和 Dashboard。核心庫不依賴 Dashboard,但是結合 Dashboard 可以取得最好的效果。
我們說的資源,可以是任何東西,服務,服務里的方法,甚至是一段代碼。使用 Sentinel 來進行資源保護,主要分為幾個步驟:
-
定義資源
-
定義規則
-
檢驗規則是否生效
先把可能需要保護的資源定義好,之后再配置規則。也可以理解為,只要有了資源,我們就可以在任何時候靈活地定義各種流量控制規則。在編碼的時候,只需要考慮這個代碼是否需要保護,如果需要保護,就將之定義為一個資源。
定義資源
1. 添加依賴
注意:在整合spring-cloud-starter-alibaba-sentinel和spring-cloud-starter-openfeign時,feign-core的版本要在10.1.0以上,即導入2.1.0.RELEASE或以上版本的openfeign,否則會報feign.RequestTemplate.path()Ljava/lang/String;異常,因為低版本openfeign的RequestTemplate類里沒有path方法
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.1.0.RELEASE</version> </dependency>
server:
port: 8080
spring:
application:
name: consumer-8080
cloud:
nacos:
discovery:
server-addr: 192.168.11.132:8848
sentinel:
transport:
dashboard: localhost:8081 # 將服務注冊到sentinel控制台
feign:
sentinel:
enabled: true #開啟feign的sentinel支持
management:
endpoints:
web:
exposure:
include: "*"
3.在controller需要保護的方法添加 @SentinelResource 注解,把方法定義為資源
@RestController public class FeignController { @Autowired private EchoService echoService; @SentinelResource(value = "echo", blockHandler = "echoBlockHandler", blockHandlerClass = EchoServiceBlockHandler.class) @GetMapping("/feign/echo/{string}") public String echo(@PathVariable("string")String string){ return echoService.echo(string); } }
@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。 @SentinelResource 注解包含以下屬性:
-
value:資源名稱,必需項(不能為空) -
entryType:entry 類型,可選項(默認為EntryType.OUT) -
blockHandler/blockHandlerClass:blockHandler對應處理BlockException的函數名稱,可選項。blockHandler 函數訪問范圍需要是public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配並且最后加一個額外的參數,類型為BlockException。blockHandler 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定blockHandlerClass為對應的類的Class對象,注意對應的函數必需為 static 函數,否則無法解析。 -
fallback:fallback 函數名稱,可選項,用於在拋出異常的時候提供 fallback 處理邏輯。fallback 函數可以針對所有類型的異常(除了exceptionsToIgnore里面排除掉的異常類型)進行處理。fallback 函數簽名和位置要求:-
返回值類型必須與原函數返回值類型一致;
-
方法參數列表需要和原函數一致,或者可以額外多一個
Throwable類型的參數用於接收對應的異常。 -
fallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定
fallbackClass為對應的類的Class對象,注意對應的函數必需為 static 函數,否則無法解析。
-
-
defaultFallback(since 1.6.0):默認的 fallback 函數名稱,可選項,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。默認 fallback 函數可以針對所以類型的異常(除了exceptionsToIgnore里面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函數簽名要求:-
返回值類型必須與原函數返回值類型一致。
-
方法參數列表需要為空,或者可以額外多一個
Throwable類型的參數用於接收對應的異常。 -
defaultFallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定
fallbackClass為對應的類的Class對象,注意對應的函數必需為 static 函數,否則無法解析。
-
-
exceptionsToIgnore(since 1.6.0):用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣拋出。
blockHandler 和 fallback區別:
blockHandler 函數會在原方法被限流/降級/系統保護的時候調用,而 fallback 函數會針對所有類型的異常。
如果一個資源同時對 blockHandler 和 fallback 都進行了配置,除了流量控制規則觸發時拋出的 BlockException 會進入 blockHandler 處理邏輯,其他規則觸發時都會進入fallback處理邏輯
4.創建EchoServiceBlockHandler類,建立blockHandler 處理邏輯
public class EchoServiceBlockHandler { private final static Logger logger = LoggerFactory.getLogger(EchoServiceBlockHandler.class); public static String echoBlockHandler(String string, BlockException e){ logger.error("error: "+e); return "方法請求降級中"; } }
在應用程序里定義規則
1.在啟動類中定義規則,並加入容器中
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class Consumer8080 { public static void main(String[] args) { SpringApplication.run(Consumer8080.class, args); } @Bean public SentinelResourceAspect sentinelResourceAspect(){ return new SentinelResourceAspect(); } //流量控制規則 @Bean public static void initFlowRule(){ List<FlowRule> rules = new ArrayList<FlowRule>(); FlowRule flowRule = new FlowRule(); flowRule.setResource("echo"); //設置資源名,即流量控制規則的作用對象 flowRule.setCount(2); //設置限流閾值,此為QPS,即每秒最高訪問量 flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); //限流閾值類型,QPS或線程數 rules.add(flowRule); FlowRuleManager.loadRules(rules); } }
2.訪問測試
訪問 http://localhost:8080/feign/echo/hi ,快速刷新,觸發流量控制規則,調用降級邏輯

在Sentinel控制台定義規則
在Sentinel控制台上我們可以簡單、靈活地管理規則以及推送規則,但是要注意的是,在Sentinel控制台上定義的規則是不會被持久化的,僅在內存中生存,當你重啟應用時,在Sentinel控制台上定義的規則將會丟失(應用程序里定義的規則在sentinel控制台上刪除,應用重啟后會重新生效)

翻譯 朗讀 復制 正在查詢,請稍候…… 重試 朗讀 復制 復制 朗讀 復制 via 谷歌翻譯(國內) 譯
