SpringCloud Alibaba (三):Sentinel 流量控制組件
SpringCloud Alibaba (三):Sentinel 流量控制組件
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); }
更多詳細內容可以參考 流量控制。
熔斷降級規則 (DegradeRule)
熔斷降級規則包含下面幾個重要的屬性:
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 | 說明 | 預設值 |
---|---|---|
highestSystemLoad | 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>
2.新增配置
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 谷歌翻譯(國內)