真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Sentinel的使用方法-創(chuàng)新互聯(lián)

1. Sentinel 是什么?

隨著微服務(wù)的流行,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要。Sentinel 以流量為切入點(diǎn),從流量控制、熔斷降級、系統(tǒng)負(fù)載保護(hù)等多個維度保護(hù)服務(wù)的穩(wěn)定性。

創(chuàng)新互聯(lián)公司是一家專業(yè)提供溫州企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)、H5建站、小程序制作等業(yè)務(wù)。10年已為溫州眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。

Sentinel 具有以下特征:

  • 豐富的應(yīng)用場景:Sentinel 承接了阿里巴巴近10年的雙十一大促流量的核心場景,例如秒殺、消息削峰填谷、集群流量控制、實(shí)時熔斷下游不可用應(yīng)用等。
  • 完備的實(shí)時監(jiān)控:Sentinel 同時提供實(shí)時的監(jiān)控功能。你可以在控制臺中看到接入應(yīng)用的單臺機(jī)器秒級數(shù)據(jù),甚至 500 臺以下規(guī)模的集群的匯總運(yùn)行情況。
  • 廣泛的開源生態(tài):Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。只需要引入相應(yīng)的依賴并進(jìn)行簡單的配置即可快速地接入 Sentinel。
  • 完善的SPI擴(kuò)展點(diǎn):Sentinel 提供簡單易用、完善的 SPI 擴(kuò)展接口。您可以通過實(shí)現(xiàn)擴(kuò)展接口來快速地定制邏輯。例如定制規(guī)則管理、適配動態(tài)數(shù)據(jù)源等。

Sentinel 的主要特性:

Sentinel的使用方法

Sentinel 的開源生態(tài):

Sentinel的使用方法

Sentinel 分為兩個部分:

  • 核心庫(Java 客戶端)不依賴任何框架/庫,能夠運(yùn)行于所有 Java 運(yùn)行時環(huán)境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持。
  • 控制臺(Dashboard)基于 Spring Boot 開發(fā),打包后可以直接運(yùn)行,不需要額外的 Tomcat 等應(yīng)用容器。

2. Sentinel 快速開始

首先,引入 Sentinel 依賴

 
   com.alibaba.csp
   sentinel-core
   1.7.1
 

接著,定義資源

資源 是 Sentinel 中的核心概念之一。最常用的資源是我們代碼中的 Java 方法。 當(dāng)然,您也可以更靈活的定義你的資源,例如,把需要控制流量的代碼用 Sentinel API SphU.entry("HelloWorld") 和 entry.exit() 包圍起來即可。在下面的例子中,我們將 System.out.println("hello world"); 作為資源(被保護(hù)的邏輯),用 API 包裝起來。例如:

try (Entry entry = SphU.entry("HelloWorld")) {
   // Your business logic here.
   System.out.println("hello world");
 } catch (BlockException e) {
   // Handle rejected request.
   e.printStackTrace();
 }
 // try-with-resources auto exit

還可以使用注解定義資源  https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

例如:

 @SentinelResource("HelloWorld")
 public void helloWorld() {
   // 資源中的邏輯
   System.out.println("hello world");
 }

最后,定義規(guī)則

接下來,通過流控規(guī)則來指定允許該資源通過的請求次數(shù),例如下面的代碼定義了資源 HelloWorld 每秒最多只能通過 20 個請求。

 private static void initFlowRules(){
   List rules = new ArrayList<>();
   FlowRule rule = new FlowRule();
   rule.setResource("HelloWorld");
   rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
   // Set limit QPS to 20.
   rule.setCount(20);
   rules.add(rule);
   FlowRuleManager.loadRules(rules);
 }

完成!

完整的代碼如下:

pom.xml

 1 
 2 
 4   4.0.0
 5   
 6     org.springframework.boot
 7     spring-boot-starter-parent
 8     2.2.2.RELEASE
 9      
10   
11   com.cjs.example
12   sentinel-example
13   0.0.1-SNAPSHOT
14   sentinel-example
15 
16   
17     1.8
18     Greenwich.SR4
19     2.1.0.RELEASE
20   
21 
22   
23     
24       org.springframework.boot
25       spring-boot-starter-actuator
26     
27     
28       org.springframework.boot
29       spring-boot-starter-web
30     
31     
32       com.alibaba.cloud
33       spring-cloud-starter-alibaba-sentinel
34     
35 
36   
37 
38   
39     
40       
41         org.springframework.cloud
42         spring-cloud-dependencies
43         ${spring-cloud.version}
44         pom
45         import
46       
47 
48       
49         com.alibaba.cloud
50         spring-cloud-alibaba-dependencies
51         ${spring-cloud-alibaba.version}
52         pom
53         import
54       
55     
56   
57 
58   
59     
60       
61         org.springframework.boot
62         spring-boot-maven-plugin
63       
64     
65   
66 
67 

application.properties

 server.port=8084
 spring.application.name=sentinel-example
 spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080

SentinelExampleApplication.java

 1 package com.cjs.example.sentinel;
 2 
 3 import com.alibaba.csp.sentinel.Entry;
 4 import com.alibaba.csp.sentinel.SphU;
 5 import com.alibaba.csp.sentinel.slots.block.BlockException;
 6 import com.alibaba.csp.sentinel.slots.block.RuleConstant;
 7 import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
 8 import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
 9 import org.springframework.boot.SpringApplication;
10 import org.springframework.boot.autoconfigure.SpringBootApplication;
11 
12 import java.util.ArrayList;
13 import java.util.List;
14 
15 @SpringBootApplication
16 public class SentinelExampleApplication {
17 
18   public static void main(String[] args) {
19     SpringApplication.run(SentinelExampleApplication.class, args);
20 
21 
22     // 配置規(guī)則.
23     initFlowRules();
24 
25     while (true) {
26       // 1.5.0 版本開始可以直接利用 try-with-resources 特性,自動 exit entry
27       try (Entry entry = SphU.entry("HelloWorld")) {
28         // 被保護(hù)的邏輯
29         System.out.println("hello world");
30       } catch (BlockException ex) {
31         // 處理被流控的邏輯
32         System.out.println("blocked!");
33       }
34     }
35   }
36 
37 
38   private static void initFlowRules() {
39     List rules = new ArrayList<>();
40 
41     FlowRule rule = new FlowRule();
42     rule.setResource("HelloWorld");
43     rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
44     // Set limit QPS to 20.
45     rule.setCount(20);
46     rules.add(rule);
47 
48     FlowRuleManager.loadRules(rules);
49 
50   }
51 }

TestController.java

 1 package com.cjs.example.sentinel;
 2 
 3 import com.alibaba.csp.sentinel.annotation.SentinelResource;
 4 import org.springframework.web.bind.annotation.GetMapping;
 5 import org.springframework.web.bind.annotation.RestController;
 6 
 7 @RestController
 8 public class TestController {
 9 
10   @GetMapping("/hello")
11   @SentinelResource("hello")
12   public String hello() {
13     return "hello";
14   }
15 
16 }

3. Sentinel 控制臺

Sentinel 控制臺最少應(yīng)該包含如下功能:

  • 查看機(jī)器列表以及健康情況:收集 Sentinel 客戶端發(fā)送的心跳包,用于判斷機(jī)器是否在線。
  • 監(jiān)控 (單機(jī)和集群聚合):通過 Sentinel 客戶端暴露的監(jiān)控 API,定期拉取并且聚合應(yīng)用監(jiān)控信息,最終可以實(shí)現(xiàn)秒級的實(shí)時監(jiān)控。
  • 規(guī)則管理和推送:統(tǒng)一管理推送規(guī)則。
  • 鑒權(quán):生產(chǎn)環(huán)境中鑒權(quán)非常重要。

https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0

獲取控制臺:

方式一:下載已經(jīng)打好的包

https://github.com/alibaba/Sentinel/releases

wget https://github.com/alibaba/Sentinel/releases/download/1.7.1/sentinel-dashboard-1.7.1.jar
方式二:通過源碼構(gòu)件 

mvn clean package

啟動控制臺

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.1.jar

默認(rèn)用戶名密碼都是sentinel

Sentinel的使用方法

Sentinel的使用方法

Sentinel的使用方法

4. Sentinel 注解支持

@SentinelResource 用于定義資源,并提供可選的異常處理和 fallback 配置項(xiàng)

@SentinelResource 注解的屬性:

  • value :資源名稱
  • entryType :the entry type (inbound or outbound)
  • blockHandler/blockHandlerClass : blockHandler 是對應(yīng)處理 BlockException 的函數(shù)名稱。blockHandler 函數(shù)訪問范圍需要是 public,返回類型需要與原方法相匹配,參數(shù)類型需要和原方法相匹配并且最后加一個額外的參數(shù),類型為 BlockException。blockHandler 函數(shù)默認(rèn)需要和原方法在同一個類中。若希望使用其他類的函數(shù),則可以指定blockHandlerClass。blockHandlerClass 為對應(yīng)函數(shù)所在類的 Class 對象,注意對應(yīng)的函數(shù)必需為 static 函數(shù),否則無法解析。
  • fallback :fallback 函數(shù)名稱,可選項(xiàng),用于在拋出異常的時候提供 fallback 處理邏輯。fallback 函數(shù)可以針對所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進(jìn)行處理。fallback 函數(shù)簽名和位置要求:defaultFallback :默認(rèn)的 fallback 函數(shù)名稱,可選項(xiàng),通常用于通用的 fallback 邏輯

    • 返回值類型必須與原函數(shù)返回值類型一致;
    • 方法參數(shù)列表需要和原函數(shù)一致,或者可以額外多一個 Throwable 類型的參數(shù)用于接收對應(yīng)的異常;
    • fallback 函數(shù)默認(rèn)需要和原方法在同一個類中。若希望使用其他類的函數(shù),則可以指定 fallbackClass 為對應(yīng)的類的 Class 對象,注意對應(yīng)的函數(shù)必需為 static 函數(shù),否則無法解析; 
  • exceptionsToIgnore :用于指定哪些異常被排除掉,不會計(jì)入異常統(tǒng)計(jì)中,也不會進(jìn)入 fallback 邏輯中,而是會原樣拋出 

需要注意的是,若 blockHandler 和 fallback 都進(jìn)行了配置,則被限流降級而拋出 BlockException 時只會進(jìn)入 blockHandler 處理邏輯。若未配置 blockHandler、fallback 和 defaultFallback,則被限流降級時會將 BlockException 直接拋出(若方法本身未定義 throws BlockException 則會被 JVM 包裝一層 UndeclaredThrowableException)。

示例:

 1 public class TestService {
 2 
 3   // 對應(yīng)的 `handleException` 函數(shù)需要位于 `ExceptionUtil` 類中,并且必須為 static 函數(shù).
 4   @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
 5   public void test() {
 6     System.out.println("Test");
 7   }
 8 
 9   // 原函數(shù)
10   @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")
11   public String hello(long s) {
12     return String.format("Hello at %d", s);
13   }
14   
15   // Fallback 函數(shù),函數(shù)簽名與原函數(shù)一致或加一個 Throwable 類型的參數(shù).
16   public String helloFallback(long s) {
17     return String.format("Halooooo %d", s);
18   }
19 
20   // Block 異常處理函數(shù),參數(shù)最后多一個 BlockException,其余與原函數(shù)一致.
21   public String exceptionHandler(long s, BlockException ex) {
22     // Do some log here.
23     ex.printStackTrace();
24     return "Oops, error occurred at " + s;
25   }
26 }

可以看到,blockHandler和fallback必須與原方法在同一個類中。如果不想寫在同一個類中,可以利用blockHandlerClass來指定類,然后通過blockHandler指定方法名。

如果同時配置了blockHandler和fallback,則BlockException只會進(jìn)到blockHandler處理邏輯中。

5. Sentinel 基本概念

資源

只要通過 Sentinel API 定義的代碼,就是資源,能夠被 Sentinel 保護(hù)起來。大部分情況下,可以使用方法簽名,URL,甚至服務(wù)名稱作為資源名來標(biāo)示資源。

規(guī)則

圍繞資源的實(shí)時狀態(tài)設(shè)定的規(guī)則,可以包括流量控制規(guī)則、熔斷降級規(guī)則以及系統(tǒng)保護(hù)規(guī)則。所有規(guī)則可以動態(tài)實(shí)時調(diào)整。

流量控制

流量控制在網(wǎng)絡(luò)傳輸中是一個常用的概念,它用于調(diào)整網(wǎng)絡(luò)包的發(fā)送數(shù)據(jù)。然而,從系統(tǒng)穩(wěn)定性角度考慮,在處理請求的速度上,也有非常多的講究。任意時間到來的請求往往是隨機(jī)不可控的,而系統(tǒng)的處理能力是有限的。我們需要根據(jù)系統(tǒng)的處理能力對流量進(jìn)行控制。Sentinel 作為一個調(diào)配器,可以根據(jù)需要把隨機(jī)的請求調(diào)整成合適的形狀,如下圖所示:

Sentinel的使用方法

流量控制有以下幾個角度:

  • 資源的調(diào)用關(guān)系,例如資源的調(diào)用鏈路,資源和資源之間的關(guān)系;
  • 運(yùn)行指標(biāo),例如 QPS、線程池、系統(tǒng)負(fù)載等;
  • 控制的效果,例如直接限流、冷啟動、排隊(duì)等; 

Sentinel 的設(shè)計(jì)理念是讓您自由選擇控制的角度,并進(jìn)行靈活組合,從而達(dá)到想要的效果。

熔斷降級

Sentinel 和 Hystrix 的原則是一致的: 當(dāng)檢測到調(diào)用鏈路中某個資源出現(xiàn)不穩(wěn)定的表現(xiàn),例如請求響應(yīng)時間長或異常比例升高的時候,則對這個資源的調(diào)用進(jìn)行限制,讓請求快速失敗,避免影響到其它的資源而導(dǎo)致級聯(lián)故障。

Sentinel的使用方法

在限制的手段上,Sentinel 和 Hystrix 采取了完全不一樣的方法。

Hystrix 通過線程池隔離的方式,來對依賴(在 Sentinel 的概念中對應(yīng) 資源)進(jìn)行了隔離。這樣做的好處是資源和資源之間做到了最徹底的隔離。缺點(diǎn)是除了增加了線程切換的成本(過多的線程池導(dǎo)致線程數(shù)目過多),還需要預(yù)先給各個資源做線程池大小的分配。 如下圖:

Sentinel的使用方法

Sentinel 對這個問題采取了兩種手段:

  • 通過并發(fā)線程數(shù)進(jìn)行限制

和資源池隔離的方法不同,Sentinel 通過限制資源并發(fā)線程的數(shù)量,來減少不穩(wěn)定資源對其它資源的影響。這樣不但沒有線程切換的損耗,也不需要您預(yù)先分配線程池的大小。當(dāng)某個資源出現(xiàn)不穩(wěn)定的情況下,例如響應(yīng)時間變長,對資源的直接影響就是會造成線程數(shù)的逐步堆積。當(dāng)線程數(shù)在特定資源上堆積到一定的數(shù)量之后,對該資源的新請求就會被拒絕。堆積的線程完成任務(wù)后才開始繼續(xù)接收請求。

  • 通過響應(yīng)時間對資源進(jìn)行降級

除了對并發(fā)線程數(shù)進(jìn)行控制以外,Sentinel 還可以通過響應(yīng)時間來快速降級不穩(wěn)定的資源。當(dāng)依賴的資源出現(xiàn)響應(yīng)時間過長后,所有對該資源的訪問都會被直接拒絕,直到過了指定的時間窗口之后才重新恢復(fù)。

系統(tǒng)負(fù)載保護(hù)

Sentinel 同時提供系統(tǒng)維度的自適應(yīng)保護(hù)能力。防止雪崩,是系統(tǒng)防護(hù)中重要的一環(huán)。當(dāng)系統(tǒng)負(fù)載較高的時候,如果還持續(xù)讓請求進(jìn)入,可能會導(dǎo)致系統(tǒng)崩潰,無法響應(yīng)。在集群環(huán)境下,網(wǎng)絡(luò)負(fù)載均衡會把本應(yīng)這臺機(jī)器承載的流量轉(zhuǎn)發(fā)到其它的機(jī)器上去。如果這個時候其它的機(jī)器也處在一個邊緣狀態(tài)的時候,這個增加的流量就會導(dǎo)致這臺機(jī)器也崩潰,最后導(dǎo)致整個集群不可用。

針對這個情況,Sentinel 提供了對應(yīng)的保護(hù)機(jī)制,讓系統(tǒng)的入口流量和系統(tǒng)的負(fù)載達(dá)到一個平衡,保證系統(tǒng)在能力范圍之內(nèi)處理最多的請求。

6. 如何使用Sentinel

Sentinel 可以簡單的分為 Sentinel 核心庫和 Dashboard。核心庫不依賴 Dashboard,但是結(jié)合 Dashboard 可以取得最好的效果。

資源,可以是任何東西,服務(wù),服務(wù)里的方法,甚至是一段代碼。使用 Sentinel 來進(jìn)行資源保護(hù),主要分為幾個步驟:

  1. 定義資源
  2. 定義規(guī)則
  3. 檢驗(yàn)規(guī)則是否生效 

在編碼的時候,只需要考慮這個代碼是否需要保護(hù),如果需要保護(hù),就將之定義為一個資源。

定義資源的常用方式

方式一: 拋出異常的方式定義資源

SphU 包含了 try-catch 風(fēng)格的 API。用這種方式,當(dāng)資源發(fā)生了限流之后會拋出 BlockException。這個時候可以捕捉異常,進(jìn)行限流之后的邏輯處理。示例代碼如下:

1 // 1.5.0 版本開始可以利用 try-with-resources 特性
2 // 資源名可使用任意有業(yè)務(wù)語義的字符串,比如方法名、接口名或其它可唯一標(biāo)識的字符串。
3 try (Entry entry = SphU.entry("resourceName")) {
4  // 被保護(hù)的業(yè)務(wù)邏輯
5  // do something here...
6 } catch (BlockException ex) {
7  // 資源訪問阻止,被限流或被降級
8  // 在此處進(jìn)行相應(yīng)的處理操作
9 }

特別地,若 entry 的時候傳入了熱點(diǎn)參數(shù),那么 exit 的時候也一定要帶上對應(yīng)的參數(shù)(exit(count, args)),否則可能會有統(tǒng)計(jì)錯誤。這個時候不能使用 try-with-resources 的方式。另外通過 Tracer.trace(ex) 來統(tǒng)計(jì)異常信息時,由于 try-with-resources 語法中 catch 調(diào)用順序的問題,會導(dǎo)致無法正確統(tǒng)計(jì)異常數(shù),因此統(tǒng)計(jì)異常信息時也不能在 try-with-resources 的 catch 塊中調(diào)用 Tracer.trace(ex)。

手動 exit 示例:

 1 Entry entry = null;
 2 // 務(wù)必保證 finally 會被執(zhí)行
 3 try {
 4  // 資源名可使用任意有業(yè)務(wù)語義的字符串,注意數(shù)目不能太多(超過 1K),超出幾千請作為參數(shù)傳入而不要直接作為資源名
 5  // EntryType 代表流量類型(inbound/outbound),其中系統(tǒng)規(guī)則只對 IN 類型的埋點(diǎn)生效
 6  entry = SphU.entry("自定義資源名");
 7  // 被保護(hù)的業(yè)務(wù)邏輯
 8  // do something...
 9 } catch (BlockException ex) {
10  // 資源訪問阻止,被限流或被降級
11  // 進(jìn)行相應(yīng)的處理操作
12 } catch (Exception ex) {
13  // 若需要配置降級規(guī)則,需要通過這種方式記錄業(yè)務(wù)異常
14  Tracer.traceEntry(ex, entry);
15 } finally {
16  // 務(wù)必保證 exit,務(wù)必保證每個 entry 與 exit 配對
17  if (entry != null) {
18   entry.exit();
19  }
20 }

熱點(diǎn)參數(shù)埋點(diǎn)示例:

 1 Entry entry = null;
 2 try {
 3   // 若需要配置例外項(xiàng),則傳入的參數(shù)只支持基本類型。
 4   // EntryType 代表流量類型,其中系統(tǒng)規(guī)則只對 IN 類型的埋點(diǎn)生效
 5   // count 大多數(shù)情況都填 1,代表統(tǒng)計(jì)為一次調(diào)用。
 6   entry = SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);
 7   // Your logic here.
 8 } catch (BlockException ex) {
 9   // Handle request rejection.
10 } finally {
11   // 注意:exit 的時候也一定要帶上對應(yīng)的參數(shù),否則可能會有統(tǒng)計(jì)錯誤。
12   if (entry != null) {
13     entry.exit(1, paramA, paramB);
14   }
15 }

SphU.entry() 的參數(shù)描述:

Sentinel的使用方法

方式二、注解方式定義資源

Sentinel 支持通過 @SentinelResource 注解定義資源并配置 blockHandler 和 fallback 函數(shù)來進(jìn)行限流之后的處理。示例:

 1 // 原本的業(yè)務(wù)方法.
 2 @SentinelResource(blockHandler = "blockHandlerForGetUser")
 3 public User getUserById(String id) {
 4   throw new RuntimeException("getUserById command failed");
 5 }
 6 
 7 // blockHandler 函數(shù),原方法調(diào)用被限流/降級/系統(tǒng)保護(hù)的時候調(diào)用
 8 public User blockHandlerForGetUser(String id, BlockException ex) {
 9   return new User("admin");
10 }

注意 blockHandler 函數(shù)會在原方法被限流/降級/系統(tǒng)保護(hù)的時候調(diào)用,而 fallback 函數(shù)會針對所有類型的異常。另外請注意 blockHandler 和 fallback 函數(shù)的形式要求。

方式三、支持異步調(diào)用

Sentinel 支持異步調(diào)用鏈路的統(tǒng)計(jì)。在異步調(diào)用中,需要通過 SphU.asyncEntry(xxx) 方法定義資源,并通常需要在異步的回調(diào)函數(shù)中調(diào)用 exit 方法。示例:

 1 try {
 2   AsyncEntry entry = SphU.asyncEntry(resourceName);
 3 
 4   // 異步調(diào)用.
 5   doAsync(userId, result -> {
 6     try {
 7       // 在此處處理異步調(diào)用的結(jié)果.
 8     } finally {
 9       // 在回調(diào)結(jié)束后 exit.
10       entry.exit();
11     }
12   });
13 } catch (BlockException ex) {
14   // Request blocked.
15   // Handle the exception (e.g. retry or fallback).
16 }

7. Sentinel 工作主流程

在 Sentinel 里面,所有的資源都對應(yīng)一個資源名稱(resourceName),每次資源調(diào)用都會創(chuàng)建一個 Entry 對象。Entry 可以通過對主流框架的適配自動創(chuàng)建,也可以通過注解的方式或調(diào)用 SphU API 顯式創(chuàng)建。Entry 創(chuàng)建的時候,同時也會創(chuàng)建一系列功能插槽(slot chain),這些插槽有不同的職責(zé),例如:

  • NodeSelectorSlot :負(fù)責(zé)收集資源的路徑,并將這些資源的調(diào)用路徑,以樹狀結(jié)構(gòu)存儲起來,用于根據(jù)調(diào)用路徑來限流降級; 
  • ClusterBuilderSlot :則用于存儲資源的統(tǒng)計(jì)信息以及調(diào)用者信息,例如該資源的 RT, QPS, thread count 等等,這些信息將用作為多維度限流,降級的依據(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ī)則,來做熔斷降級;
  • SystemSlot :則通過系統(tǒng)的狀態(tài),例如 load1 等,來控制總的入口流量;

總體架構(gòu)圖如下:

Sentinel的使用方法

這個彩色的圖貌似更好看一點(diǎn)兒

Sentinel的使用方法

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

Sentinel的使用方法

8. Sentinel 流量控制

流量控制(flow control),其原理是監(jiān)控應(yīng)用流量的 QPS 或并發(fā)線程數(shù)等指標(biāo),當(dāng)達(dá)到指定的閾值時對流量進(jìn)行控制,以避免被瞬時的流量高峰沖垮,從而保障應(yīng)用的高可用性。

FlowSlot 會根據(jù)預(yù)設(shè)的規(guī)則,結(jié)合前面 NodeSelectorSlotClusterNodeBuilderSlot、StatisticSlot 統(tǒng)計(jì)出來的實(shí)時信息進(jìn)行流量控制。

限流的直接表現(xiàn)是在執(zhí)行 Entry nodeA = SphU.entry(resourceName) 的時候拋出 FlowException 異常。FlowException 是 BlockException 的子類,您可以捕捉 BlockException 來自定義被限流之后的處理邏輯。

同一個資源可以創(chuàng)建多條限流規(guī)則。FlowSlot 會對該資源的所有限流規(guī)則依次遍歷,直到有規(guī)則觸發(fā)限流或者所有規(guī)則遍歷完畢。

一條限流規(guī)則主要由下面幾個因素組成,我們可以組合這些元素來實(shí)現(xiàn)不同的限流效果:

  • resource :資源名,即限流規(guī)則的作用對象
  • count :限流閾值
  • grade :限流閾值類型(QPS 或并發(fā)線程數(shù))
  • limitApp :流控針對的調(diào)用來源,若為 default 則不區(qū)分調(diào)用來源
  • strategy :調(diào)用關(guān)系限流策略
  • controlBehavior :流量控制效果(直接拒絕、Warm Up、勻速排隊(duì)) 
8.1. 基于QPS/并發(fā)數(shù)的流量控制

流量控制主要有兩種統(tǒng)計(jì)類型,一種是統(tǒng)計(jì)并發(fā)線程數(shù),另外一種則是統(tǒng)計(jì) QPS。類型由 FlowRule 的 grade 字段來定義。其中,0 代表根據(jù)并發(fā)數(shù)量來限流,1 代表根據(jù) QPS 來進(jìn)行流量控制。其中線程數(shù)、QPS 值,都是由 StatisticSlot 實(shí)時統(tǒng)計(jì)獲取的。

可以通過下面的命令查看實(shí)時統(tǒng)計(jì)信息:

curl http://localhost:8719/cnode?id=resourceName

并發(fā)線程數(shù)流量控制

并發(fā)線程數(shù)限流用于保護(hù)業(yè)務(wù)線程數(shù)不被耗盡。例如,當(dāng)應(yīng)用所依賴的下游應(yīng)用由于某種原因?qū)е路?wù)不穩(wěn)定、響應(yīng)延遲增加,對于調(diào)用者來說,意味著吞吐量下降和更多的線程數(shù)占用,極端情況下甚至導(dǎo)致線程池耗盡。為應(yīng)對太多線程占用的情況,業(yè)內(nèi)有使用隔離的方案,比如通過不同業(yè)務(wù)邏輯使用不同線程池來隔離業(yè)務(wù)自身之間的資源爭搶(線程池隔離)。這種隔離方案雖然隔離性比較好,但是代價就是線程數(shù)目太多,線程上下文切換的 overhead 比較大,特別是對低延時的調(diào)用有比較大的影響。Sentinel 并發(fā)線程數(shù)限流不負(fù)責(zé)創(chuàng)建和管理線程池,而是簡單統(tǒng)計(jì)當(dāng)前請求上下文的線程數(shù)目,如果超出閾值,新的請求會被立即拒絕,效果類似于信號量隔離。

QPS流量控制

當(dāng) QPS 超過某個閾值的時候,則采取措施進(jìn)行流量控制。流量控制的效果包括以下幾種:直接拒絕、Warm Up、勻速排隊(duì)。對應(yīng) FlowRule 中的 controlBehavior 字段。

8.2. 基于調(diào)用關(guān)系的流量控制

調(diào)用關(guān)系包括調(diào)用方、被調(diào)用方;一個方法又可能會調(diào)用其它方法,形成一個調(diào)用鏈路的層次關(guān)系。Sentinel 通過 NodeSelectorSlot 建立不同資源間的調(diào)用的關(guān)系,并且通過 ClusterNodeBuilderSlot 記錄每個資源的實(shí)時統(tǒng)計(jì)信息。

有了調(diào)用鏈路的統(tǒng)計(jì)信息,我們可以衍生出多種流量控制手段。

根據(jù)調(diào)用方限流

ContextUtil.enter(resourceName, origin) 方法中的 origin 參數(shù)標(biāo)明了調(diào)用方身份。這些信息會在 ClusterBuilderSlot 中被統(tǒng)計(jì)。可通過以下命令來展示不同的調(diào)用方對同一個資源的調(diào)用數(shù)據(jù):

根據(jù)調(diào)用鏈路入口限流:鏈路限流

NodeSelectorSlot 中記錄了資源之間的調(diào)用鏈路,這些資源通過調(diào)用關(guān)系,相互之間構(gòu)成一棵調(diào)用樹。這棵樹的根節(jié)點(diǎn)是一個名字為 machine-root 的虛擬節(jié)點(diǎn),調(diào)用鏈的入口都是這個虛節(jié)點(diǎn)的子節(jié)點(diǎn)。

一棵典型的調(diào)用樹如下圖所示:

Sentinel的使用方法

具有關(guān)系的資源流量控制:關(guān)聯(lián)流量控制

當(dāng)兩個資源之間具有資源爭搶或者依賴關(guān)系的時候,這兩個資源便具有了關(guān)聯(lián)。比如對數(shù)據(jù)庫同一個字段的讀操作和寫操作存在爭搶,讀的速度過高會影響寫得速度,寫的速度過高會影響讀的速度。如果放任讀寫操作爭搶資源,則爭搶本身帶來的開銷會降低整體的吞吐量。可使用關(guān)聯(lián)限流來避免具有關(guān)聯(lián)關(guān)系的資源之間過度的爭搶,舉例來說,read_db 和 write_db 這兩個資源分別代表數(shù)據(jù)庫讀寫,我們可以給 read_db 設(shè)置限流規(guī)則來達(dá)到寫優(yōu)先的目的:設(shè)置 FlowRule.strategy 為 RuleConstant.RELATE 同時設(shè)置 FlowRule.ref_identity 為 write_db。這樣當(dāng)寫庫操作過于頻繁時,讀數(shù)據(jù)的請求會被限流。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


分享題目:Sentinel的使用方法-創(chuàng)新互聯(lián)
網(wǎng)站路徑:http://weahome.cn/article/dojdho.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部