GitHub官方:https://github.com/alibaba/Sentinel
官方文檔:https://sentinelguard.io/zh-cn/index.html
微服務SpringCloudAlibaba——簡介(1)
微服務SpringClout Alibaba——Nacos注冊中心、配置中心和Nacos叢集(2)
微服務SpringClout Alibaba——Sentinel流控、熔斷、降級(3)
微服務SpringClout Alibaba——Seata分布式事務(4)
微服務SpringCloud——GateWay網關(5)
目錄
一、Sentinel介紹
二、基本使用
三、流控規則
1、概述
二、熔斷降級
1、概述
2、熔斷政策
三、熱點參數限流
1、概述——Overview
代碼測試
四、系統自适應限流
五、Sentinel服務熔斷OpenFeign
熔斷架構比較
六、Sentinel持久化
一、Sentinel介紹
Sentinel 是面向分布式服務架構的流量控制元件,主要以流量為切入點,從流量控制、熔斷降級、系統自适應保護等多個次元來幫助您保障微服務的穩定性。
Sentinel 具有以下特征:
- 豐富的應用場景:Sentinel 承接了阿裡巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、叢集流量控制、實時熔斷下遊不可用應用等。
- 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級資料,甚至 500 台以下規模的叢集的彙總運作情況。
- 廣泛的開源生态:Sentinel 提供開箱即用的與其它開源架構/庫的整合子產品,例如與 Spring Cloud、Dubbo、gRPC 的整合。您隻需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
- 完善的 SPI 擴充點:Sentinel 提供簡單易用、完善的 SPI 擴充接口。您可以通過實作擴充接口來快速地定制邏輯。例如定制規則管理、适配動态資料源等。
Sentinel主要特性:
二、基本使用
GitHub下載下傳位址:https://github.com/alibaba/Sentinel/releases/tag/v1.8.0
Sentinel預設的端口是8080,根據需要更改端口運作:java -Dserver.port=8081 -jar sentinel-dashboard-1.8.0.jar
Sentinel的預設賬号密碼到時sentinel
建立一個簡單的項目測試:
pom的引入:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 持久化 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
properties的配置:
server.port=8401
spring.application.name=springcloud-alibaba-sentinel
#nacos服務位址
spring.cloud.nacos.discovery.server-addr=192.168.226.137:81
#sentinel服務位址
spring.cloud.sentinel.transport.dashboard=localhost:8081
#預設8719,假如被占用了會自動從8719開始依次+1掃描。直至找到未被占用的端口
spring.cloud.sentinel.transport.port=8719
management.endpoints.web.exposure.include=*
Controller:
@RestController
public class FlowLimitController
{
@GetMapping("/testA")
public String testA() {
return "------testA";
}
@GetMapping("/testB")
public String testB() {
return "------testB";
}
}
啟動項目:
發現sentinel沒有監控到服務,别急,那是因為sentinel啟用的賴加載的方式,當通路了項目的連結的時候就會觸發,當通路一次之後:
三、流控規則
1、概述
流量控制(flow control),其原理是監控應用流量的 QPS 或并發線程數等名額,當達到指定的門檻值時對流量進行控制,以避免被瞬時的流量高峰沖垮,進而保障應用的高可用性。
- 資源名:唯一名稱,預設請求路勁
- 針對來源:Sentinel可以針對調用者進行限流,填寫微服務名,預設default(不區分來源)
- 門檻值類型/單機門檻值
- QPS(每秒鐘請求數量):當調用該API的QPS達到門檻值的時候,進行限流
- 線程數:當調用該API的線程數達到門檻值的時候,進行限流
- 是否叢集:不需要叢集
- 流量模式:
- 直接:API達到限流天劍時,直接限流
- 關聯:當關聯的資源達到門檻值時,就限流自己
- 鍊路:隻記錄指定鍊路上的流量(指定資源從入口資源進來的流量,如果達到門檻值,就進行限流)【API級别的針對來源】
- 流控效果:
- 快速失敗:直接失敗,抛異常
- Warm Up:根據codeFactor(冷加載因子,預設3)的值,從門檻值/codeFactor,經過預熱時長,才達到設定的QPS門檻值,例如:運作5s後,能每秒可以通路10個,防止流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮(可運用到秒殺)
- 排隊等待:勻速排隊,讓請求勻速的速度通過,門檻值類型必須設定未QPS,否則無效
二、熔斷降級
1、概述
除了流量控制以外,對調用鍊路中不穩定的資源進行熔斷降級也是保障高可用的重要措施之一。由于調用關系的複雜性,如果調用鍊路中的某個資源不穩定,最終會導緻請求發生堆積。Sentinel 熔斷降級會在調用鍊路中某個資源出現不穩定狀态時(例如調用逾時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而導緻級聯錯誤。當資源被降級後,在接下來的降級時間視窗之内,對該資源的調用都自動熔斷(預設行為是抛出
DegradeException
)。
2、熔斷政策
- 慢調用比例 (
):選擇以慢調用比例作為門檻值,需要設定允許的慢調用 RT(即最大的響應時間),請求的響應時間大于該值則統計為慢調用。當機關統計時長(SLOW_REQUEST_RATIO
)内請求數目大于設定的最小請求數目,并且慢調用的比例大于門檻值,則接下來的熔斷時長内請求會自動被熔斷。經過熔斷時長後熔斷器會進入探測恢複狀态(HALF-OPEN 狀态),若接下來的一個請求響應時間小于設定的慢調用 RT 則結束熔斷,若大于設定的慢調用 RT 則會再次被熔斷。statIntervalMs
- 異常比例 (
):當資源的每秒請求量 >= N(可配置),并且每秒異常總數占通過量的比值超過門檻值(DEGRADE_GRADE_EXCEPTION_RATIO
中的DegradeRule
)之後,資源進入降級狀态,即在接下的時間視窗(count
中的DegradeRule
,以 s 為機關)之内,對這個方法的調用都會自動地傳回。異常比率的門檻值範圍是timeWindow
,代表 0% - 100%。[0.0, 1.0]
- 異常數 (
):當資源近 1 分鐘的異常數目超過門檻值之後會進行熔斷。注意由于統計時間視窗是分鐘級别的,若DEGRADE_GRADE_EXCEPTION_COUNT
小于 60s,則結束熔斷狀态後仍可能再進入熔斷狀态。timeWindow
注意:異常降級僅針對業務異常,對 Sentinel 限流降級本身的異常(
BlockException
)不生效。為了統計異常比例或異常數,需要通過
Tracer.trace(ex)
記錄業務異常。
三、熱點參數限流
1、概述——Overview
何為熱點?熱點即經常通路的資料。很多時候我們希望統計某個熱點資料中通路頻次最高的 Top K 資料,并對其通路進行限制。比如:
- 商品 ID 為參數,統計一段時間内最常購買的商品 ID 并進行限制
- 使用者 ID 為參數,針對一段時間内頻繁通路的使用者 ID 進行限制
熱點參數限流會統計傳入參數中的熱點參數,并根據配置的限流門檻值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。
代碼測試
1、基礎配置
/**
* @SentinelResource:當某個方法出問題時,自定義對應的兜底降級方法,
* value:sentinel上熱點規則的資源名,blockHandlerClass:具體是那個類(不配置則預設本類),blockHandler:兜底方法(不配置該方法将顯示500頁面),fallback:代碼異常兜底,exceptionsToIgnore = {IllegalArgumentException.class}:忽略指定異常,即這些異常不用兜底方法處理
* @param p1
* @param p2
* @return
*/
@GetMapping("testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
@RequestParam(value = "p2",required = false) String p2){
return "--------testHotKey";
}
public String deal_testHotKey(String p1, String p2, BlockException blockException){
return "--------deal_testHotKey,自定義,兜底";
}
參數索引:0(即p1),1s中隻允許限流1次:
結果:
2、進階配置——參數例外項
例如:當使用者是VIP是就1s中限流200次,别的使用者1s中限流1次
結果:
注意:@SentinelResource主管配置出錯,運作出錯該走異常走異常
四、系統自适應限流
Sentinel 系統自适應限流從整體次元對應用入口流量進行控制,結合應用的 Load、CPU 使用率、總體平均 RT、入口 QPS 和并發線程數等幾個次元的監控名額,通過自适應的流控政策,讓系統的入口流量和系統的負載達到一個平衡,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。
系統規則
系統保護規則是從應用級别的入口流量進行控制,從單台機器的 load、CPU 使用率、平均 RT、入口 QPS 和并發線程數等幾個次元監控應用名額,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。
系統保護規則是應用整體次元的,而不是資源次元的,并且僅對入口流量生效。入口流量指的是進入應用的流量(
EntryType.IN
),比如 Web 服務或 Dubbo 服務端接收的請求,都屬于入口流量。
系統規則支援以下的模式:
- Load 自适應(僅對 Linux/Unix-like 機器生效):系統的 load1 作為啟發名額,進行自适應系統保護。當系統 load1 超過設定的啟發值,且系統目前的并發線程數超過估算的系統容量時才會觸發系統保護(BBR 階段)。系統容量由系統的
估算得出。設定參考值一般是maxQps * minRt
。CPU cores * 2.5
- CPU usage(1.5.0+ 版本):當系統 CPU 使用率超過門檻值即觸發系統保護(取值範圍 0.0-1.0),比較靈敏。
- 平均 RT:當單台機器上所有入口流量的平均 RT 達到門檻值即觸發系統保護,機關是毫秒。
- 并發線程數:當單台機器上所有入口流量的并發線程數達到門檻值即觸發系統保護。
- 入口 QPS:當單台機器上所有入口流量的 QPS 達到門檻值即觸發系統保護。
五、Sentinel服務熔斷OpenFeign
Feign元件一般是消費側
1、POM
<!--SpringCloud openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、配置檔案添加:
#激活Sentinel對Feign的支援
feign.sentinel.enabled=true
3、主啟動類(main)添加:@EnableFeignClients
4、業務類:
帶@Feignclient注解的業務接口,使用 fallback = OpenFeignFallbackService.class 進行兜底
/**
* @author 小懶蟲
*/
@FeignClient(value = "springcloud-alibaba-payment",fallback = OpenFeignFallbackService.class)
public interface OpenFeignService {
@GetMapping(value = "/payment/nacos/{id}")
String getPayment(@PathVariable("id") Integer id);
}
/**
* @author 小懶蟲
*/
@Component
public class OpenFeignFallbackService implements OpenFeignService {
@Override
public String getPayment(Integer id) {
return "服務降級傳回,---OpenFeignFallbackService";
}
}
5、Controller層:
@Resource
private OpenFeignService openFeignService;
@GetMapping(value = "/consumer/payment/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id){
return openFeignService.getPayment(id);
}
正常運作:
當服務端出問題時(即我們故意停掉),消費端則自動降級,進入兜底方法:
熔斷架構比較
Sentinel | Hystrix | resilience4j | |
---|---|---|---|
隔離政策 | 信号量隔離(并發線程數限流) | 線程池隔商/信号量隔離 | 信号量隔離 |
熔斷降級政策 | 基于響應時間、異常比率、異常數 | 基于異常比率 | 基于異常比率、響應時間 |
實時統計實作 | 滑動視窗(LeapArray) | 滑動視窗(基于RxJava) | Ring Bit Buffer |
動态規則配置 | 支援多種資料源 | 支援多種資料源 | 有限支援 |
擴充性 | 多個擴充點 | 插件的形式 | 接口的形式 |
基于注解的支援 | 支援 | 支援 | 支援 |
限流 | 基于QPS,支援基于調用關系的限流 | 有限的支援 | Rate Limiter |
流量整形 | 支援預熱模式勻速器模式、預熱排隊模式 | 不支援 | 簡單的Rate Limiter模式 |
系統自适應保護 | 支援 | 不支援 | 不支援 |
控制台 | 提供開箱即用的控制台,可配置規則、檢視秒級監控,機器發觀等 | 簡單的監控檢視 | 不提供控制台,可對接其它監控系統 |
六、Sentinel持久化
将限流配置規則持久化進Nacos儲存
POM
<!--SpringCloud ailibaba sentinel-datasource-nacos 後續做持久化用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
配置檔案添加:
#将sentinel配置到nacos中做持久化
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=192.168.226.137:80
spring.cloud.sentinel.datasource.ds1.nacos.data-id=cloudalibaba-sentinel-service
spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.data-type=json
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow
nacos添加配置檔案
配置内容解析
[{
"resource": "/testHotKey",
"IimitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}]
resource:資源名稱;
limitApp:來源應用;
grade:門檻值類型,0表示線程數, 1表示QPS;
count:單機門檻值;
strategy:流控模式,0表示直接,1表示關聯,2表示鍊路;
controlBehavior:流控效果,0表示快速失敗,1表示Warm Up,2表示排隊等待;
clusterMode:是否叢集。
當通路一次後檢視sentinel,持久化生效: