Sentinel 是什麼?
隨着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 以流量爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
Sentinel 具有以下特徵:
- 豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峯填谷、集羣流量控制、實時熔斷下游不可用應用等。
- 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制檯中看到接入應用的單臺機器秒級數據,甚至500臺以下規模的集羣的彙總運行情況。
- 廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Apache Dubbo、gRPC、Quarkus的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。同時 Sentinel 提供 Java/Go/C++ 等多語言的原生實現。
- 完善的 SPI 擴展機制:Sentinel提供簡單易用、完善的SPI擴展接口。您可以通過實現擴展接口來快速地定製邏輯。例如定製規則管理、適配動態數據源等。
Setinel的主要特性:
Setinel分爲兩個部分:
- 核心庫(Java客戶端)不依賴任何框架/庫,能夠運行於所有Java運行時環境,同時對Dubbo/Spring Cloud等框架也有較好的支持。
- 控制檯(Dashboard)基於Spring Boot開發,打包後可以直接運行,不需要額外的Tomcat等應用容器。
快速開始
- Sentinel Dashboard部署,下載地址:https://github.com/alibaba/Sentinel/releases ,使用命令啓動
java -jar sentinel-dashboard-1.8.3.jar
-
登錄控制檯,地址: http://localhost:8080 初始賬密:sentinel/sentinel
-
引入依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 在服務的application.properties中加入以下配置
spring:
application:
name: resume-nacos-consumer
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
port: 8719 #sentinel會在該端口啓動http server,那麼這樣的話,控制檯定義的一些限流等規則才能發送傳遞過來
然後調用接口,再查看Sentinel控制檯(注意有一會兒的延遲)。
Sentinel關鍵概念
概念名稱 | 概念描述 |
---|---|
資源 | 它可以是Java應⽤程序中的任何內容。例如,由應⽤程序提供的服務或由應⽤程序調⽤的其它應⽤提供的服務,甚⾄可以是⼀段代碼。我們請求的API接⼝就是資源 |
規則 | 圍繞資源的實時狀態設定的規則,可以包括流量控制規則、熔斷降級規則以及系統保護規則。所有規則可以動態實時調整 |
流控實戰
- 資源名:默認請求的路徑
- 針對來源:可以填寫微服務名稱,Sentinel支持針對調用者進行限流。默認是default(不區分來源)
- 閾值類型:QPS和線程數
- 流控模式:
- 直接:資源調⽤達到限流條件時,直接限流
- 關聯:填寫一個關聯資源,關聯的資源達到閾值了,也限流自己這個資源(資源名處配置的資源)
- 鏈路:如果有多個鏈路都可以調用到本資源,可以指定只記錄某個鏈路上的流量
- 流控效果:
- 快速失敗:直接失敗,拋出異常
- Warm Up:根據冷加載因子(默認3)的值,從(閾值/冷加載因子)經過預熱時長後才能達到設置的QPS閾值。因爲有時系統沒預熱的時候它的QPS達不到那麼高,所以最開始不能放那麼高的閾值的流量進來。
- 排隊等待:多餘請求勻速排隊,讓請求勻速通過,閾值類型必須設置爲QPS,否則無效。
降級實戰
Sentinel降級會在調⽤鏈路中某個資源出現不穩定狀態時(例如調⽤超時或異常⽐例升⾼),對這個資源的調⽤進⾏限制,讓請求快速失敗,避免影響到其它的資源⽽導致級聯錯誤。當資源被降級後,在接下來的降級時間窗⼝之內,對該資源的調⽤都⾃動熔斷
慢調用比例:
- 最大RT:代表設定一個時間,超過這個時間就認定爲慢響應
- 比例閾值:超過多少比例進入熔斷
- 熔斷時長
- 最小請求數:超過最小請求數才能生效
這個版本下好像有bug,比例閾值填不了
異常比例:
異常比例超過0.5就會熔斷
異常數:
異常數超過2就會被熔斷,上面熔斷後,會直接拋出異常。像下面這樣:
實際應用中,我們需要對異常進行自定義。
3.1 自定義降級異常
使用blockHandler:
@RequestMapping("/testException")
@SentinelResource(value = "/testExceptionTest",blockHandlerClass = SentinelFallback.class,blockHandler = "handleException")
public String testException(){
int i=1/0;
return "ok";
}
public class SentinelFallback {
/**
* 形參最後加入BlockException參數,用於接收異常,方法必須爲public static
* @param blockException
* @return
*/
public static String handleException(BlockException blockException){
return "exception";
}
}
使用fallback:
@RequestMapping("/testError")
@SentinelResource(value = "/testErrorTest",fallbackClass = SentinelFallback.class,fallback = "handleError")
public String testError(){
int i=1/0;
return "ok";
}
public class SentinelFallback {
//方法列表需要和原函數一致,或者多一個Throwable類型的參數
public static String handleError(){
return "error";
}
}
fallback和blockHandler的區別:fallback可以處理所有類型的異常,而blockHandler只處理BlockException類型的異常。
3.2 基於Nacos實現Sentinel規則持久化
- 引入依賴
<!-- Sentinel支持採用Nacos作爲規則配置數據源 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
- sentinel中配置Nacos數據源
spring:
application:
name: resume-nacos-consumer
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
port: 8719 #sentinel會在該端口啓動http server,那麼這樣的話,控制檯定義的一些限流等規則才能發送傳遞過來
datasource:
flow: # 名稱是自定義的
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
data-id: ${spring.application.name}-flow-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow # 類型來⾃RuleType類
degrade: # 名稱是自定義的
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
data-id: ${spring.application.name}-degrade-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: degrade # 類型來⾃RuleType類
- 在Nacos裏面進行配置
配置完後我們發現Sentinel裏面就有了
- 配置說明
所有屬性來⾃源碼FlowRule類
- resource:資源名稱
- limitApp:來源應⽤
- grade:閾值類型 0 線程數 1 QPS
- count:單機閾值
- strategy:流控模式,0 直接 1 關聯 2 鏈路
- controlBehavior:流控效果,0 快速失敗 1 Warm Up 2 排隊等待
- clusterMode:true/false 是否集羣
降級配置規則:
配置文件: resume-nacos-consumer-degrade-rules
[
{
"resource":"findResumeOpenState",
"grade":2,
"count":1,
"timeWindow":5
}
]
所有屬性來⾃源碼DegradeRule類
- resource:資源名稱
- grade:降級策略 0 RT 1 異常⽐例 2 異常數
- count:閾值
- timeWindow:時間窗
注意
- ⼀個資源可以同時有多個限流規則和降級規則,所以配置的數據是⼀個json數組
- Sentinel控制檯中修改規則,僅是內存中⽣效,不會修改Nacos中的配置值,重啓後恢復原來的值;而在Nacos控制檯中修改規則,不僅內存中⽣效,Nacos中持久化規則也⽣效,重啓後規則依然保持。