Spring?Boot整合流控組件Sentinel的場(chǎng)景分析
一、百度百科
Sentinel 是面向分布式服務(wù)架構(gòu)的高可用流量防護(hù)組件,主要以流量為切入點(diǎn),從限流、流量整形、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)、熱點(diǎn)防護(hù)等多個(gè)維度來(lái)幫助開發(fā)者保障微服務(wù)的穩(wěn)定性。
1、Sentinel 特性
豐富的應(yīng)用場(chǎng)景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場(chǎng)景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)、消息削峰填谷、集群流量控制、實(shí)時(shí)熔斷下游不可用應(yīng)用等。
完備的實(shí)時(shí)監(jiān)控:Sentinel 同時(shí)提供實(shí)時(shí)的監(jiān)控功能。您可以在控制臺(tái)中看到接入應(yīng)用的單臺(tái)機(jī)器秒級(jí)數(shù)據(jù),甚至 500 臺(tái)以下規(guī)模的集群的匯總運(yùn)行情況。
廣泛的開源生態(tài):Sentinel 提供開箱即用的與其它開源框架/庫(kù)的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應(yīng)的依賴并進(jìn)行簡(jiǎn)單的配置即可快速地接入 Sentinel。
完善的 SPI 擴(kuò)展點(diǎn):Sentinel 提供簡(jiǎn)單易用、完善的 SPI 擴(kuò)展接口。您可以通過實(shí)現(xiàn)擴(kuò)展接口來(lái)快速地定制邏輯。例如定制規(guī)則管理、適配動(dòng)態(tài)數(shù)據(jù)源等。

2、Sentinel 的開源生態(tài)

二、Sentinel 的歷史
2012 年,Sentinel 誕生,主要功能為入口流量控制。
2013-2017 年,Sentinel 在阿里巴巴集團(tuán)內(nèi)部迅速發(fā)展,成為基礎(chǔ)技術(shù)模塊,覆蓋了所有的核心場(chǎng)景。Sentinel 也因此積累了大量的流量歸整場(chǎng)景以及生產(chǎn)實(shí)踐。
2018 年,Sentinel 開源,并持續(xù)演進(jìn)。
2019 年,Sentinel 朝著多語(yǔ)言擴(kuò)展的方向不斷探索,推出C++原生版本,同時(shí)針對(duì) Service Mesh 場(chǎng)景也推出了Envoy 集群流量控制支持,以解決 Service Mesh 架構(gòu)下多語(yǔ)言限流的問題。
2020 年,推出Sentinel Go 版本,繼續(xù)朝著云原生方向演進(jìn)。
三、Sentinel 基本概念
1、資源
資源是 Sentinel 的關(guān)鍵概念。它可以是 Java 應(yīng)用程序中的任何內(nèi)容,例如,由應(yīng)用程序提供的服務(wù),或由應(yīng)用程序調(diào)用的其它應(yīng)用提供的服務(wù),甚至可以是一段代碼。在接下來(lái)的文檔中,我們都會(huì)用資源來(lái)描述代碼塊。
只要通過 Sentinel API 定義的代碼,就是資源,能夠被 Sentinel 保護(hù)起來(lái)。大部分情況下,可以使用方法簽名,URL,甚至服務(wù)名稱作為資源名來(lái)標(biāo)示資源。
2、規(guī)則
圍繞資源的實(shí)時(shí)狀態(tài)設(shè)定的規(guī)則,可以包括流量控制規(guī)則、熔斷降級(jí)規(guī)則以及系統(tǒng)保護(hù)規(guī)則。所有規(guī)則可以動(dòng)態(tài)實(shí)時(shí)調(diào)整。
四、sentinel的優(yōu)勢(shì)
友好的控制面板
支持實(shí)時(shí)監(jiān)控
支持多種限流,比如QPS限流,線程數(shù)以及多種限流策略
支持多種降級(jí)模式,支持按平均返回時(shí)間降級(jí),按多種異常數(shù)降級(jí),按異常比例降級(jí)等
方便擴(kuò)展開發(fā),支持SPI模式對(duì)chain進(jìn)行擴(kuò)展
支持鏈路的關(guān)聯(lián),可以實(shí)現(xiàn)按鏈路統(tǒng)計(jì)限流,系統(tǒng)保護(hù),熱門資源保護(hù)等等
五、Sentinel 功能和設(shè)計(jì)理念
1、什么是流量控制
流量控制在網(wǎng)絡(luò)傳輸中是一個(gè)常用的概念,它用于調(diào)整網(wǎng)絡(luò)包的發(fā)送數(shù)據(jù)。然而,從系統(tǒng)穩(wěn)定性角度考慮,在處理請(qǐng)求的速度上,也有非常多的講究。任意時(shí)間到來(lái)的請(qǐng)求往往是隨機(jī)不可控的,而系統(tǒng)的處理能力是有限的。我們需要根據(jù)系統(tǒng)的處理能力對(duì)流量進(jìn)行控制。Sentinel 作為一個(gè)調(diào)配器,可以根據(jù)需要把隨機(jī)的請(qǐng)求調(diào)整成合適的形狀,如下圖所示:

2、流量控制設(shè)計(jì)理念
流量控制有以下幾個(gè)角度:
資源的調(diào)用關(guān)系,例如資源的調(diào)用鏈路,資源和資源之間的關(guān)系;
運(yùn)行指標(biāo),例如 QPS、線程池、系統(tǒng)負(fù)載等;
控制的效果,例如直接限流、冷啟動(dòng)、排隊(duì)等。
Sentinel 的設(shè)計(jì)理念是讓您自由選擇控制的角度,并進(jìn)行靈活組合,從而達(dá)到想要的效果。
3、什么是熔斷降級(jí)
除了流量控制以外,及時(shí)對(duì)調(diào)用鏈路中的不穩(wěn)定因素進(jìn)行熔斷也是 Sentinel 的使命之一。由于調(diào)用關(guān)系的復(fù)雜性,如果調(diào)用鏈路中的某個(gè)資源出現(xiàn)了不穩(wěn)定,可能會(huì)導(dǎo)致請(qǐng)求發(fā)生堆積,進(jìn)而導(dǎo)致級(jí)聯(lián)錯(cuò)誤。

Sentinel 和 Hystrix 的原則是一致的: 當(dāng)檢測(cè)到調(diào)用鏈路中某個(gè)資源出現(xiàn)不穩(wěn)定的表現(xiàn),例如請(qǐng)求響應(yīng)時(shí)間長(zhǎng)或異常比例升高的時(shí)候,則對(duì)這個(gè)資源的調(diào)用進(jìn)行限制,讓請(qǐng)求快速失敗,避免影響到其它的資源而導(dǎo)致級(jí)聯(lián)故障。
這里是引用Hystrix源自Netflix API團(tuán)隊(duì)于2011年開始的彈性工程工作。2012年Hystrix不斷發(fā)展和成熟,Netflix內(nèi)的許多團(tuán)隊(duì)都采用了它。如今,每天在Netflix執(zhí)行數(shù)以千億計(jì)的線程隔離和數(shù)以千計(jì)的信號(hào)隔離調(diào)用,這大大的提高了運(yùn)行時(shí)間和彈性。
4、熔斷降級(jí)設(shè)計(jì)理念
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一樣的方法。
Hystrix 通過線程池隔離的方式,來(lái)對(duì)依賴(在 Sentinel 的概念中對(duì)應(yīng) 資源)進(jìn)行了隔離。這樣做的好處是資源和資源之間做到了最徹底的隔離。缺點(diǎn)是除了增加了線程切換的成本(過多的線程池導(dǎo)致線程數(shù)目過多),還需要預(yù)先給各個(gè)資源做線程池大小的分配,并且對(duì)于一些使用了 ThreadLocal 的場(chǎng)景來(lái)說會(huì)有問題(如 Spring 事務(wù))。
Sentinel 對(duì)這個(gè)問題采取了兩種手段:
(1)通過并發(fā)線程數(shù)進(jìn)行限制
和資源池隔離的方法不同,Sentinel 通過限制資源并發(fā)線程的數(shù)量,來(lái)減少不穩(wěn)定資源對(duì)其它資源的影響。這樣不但沒有線程切換的損耗,也不需要您預(yù)先分配線程池的大小。當(dāng)某個(gè)資源出現(xiàn)不穩(wěn)定的情況下,例如響應(yīng)時(shí)間變長(zhǎng),對(duì)資源的直接影響就是會(huì)造成線程數(shù)的逐步堆積。當(dāng)線程數(shù)在特定資源上堆積到一定的數(shù)量之后,對(duì)該資源的新請(qǐng)求就會(huì)被拒絕。堆積的線程完成任務(wù)后才開始繼續(xù)接收請(qǐng)求。
(2)針對(duì)慢調(diào)用和異常對(duì)資源進(jìn)行降級(jí)
除了對(duì)并發(fā)線程數(shù)進(jìn)行控制以外,Sentinel 還可以根據(jù)響應(yīng)時(shí)間和異常等不穩(wěn)定因素來(lái)快速對(duì)不穩(wěn)定的調(diào)用進(jìn)行熔斷。當(dāng)依賴的資源出現(xiàn)響應(yīng)時(shí)間過長(zhǎng)后,所有對(duì)該資源的訪問都會(huì)被直接拒絕,直到過了指定的時(shí)間窗口之后才重新漸進(jìn)式地恢復(fù)。
5、系統(tǒng)自適應(yīng)保護(hù)
Sentinel 同時(shí)提供系統(tǒng)維度的自適應(yīng)保護(hù)能力。防止雪崩,是系統(tǒng)防護(hù)中重要的一環(huán)。當(dāng)系統(tǒng)負(fù)載較高的時(shí)候,如果還持續(xù)讓請(qǐng)求進(jìn)入,可能會(huì)導(dǎo)致系統(tǒng)崩潰,無(wú)法響應(yīng)。在集群環(huán)境下,網(wǎng)絡(luò)負(fù)載均衡會(huì)把本應(yīng)這臺(tái)機(jī)器承載的流量轉(zhuǎn)發(fā)到其它的機(jī)器上去。如果這個(gè)時(shí)候其它的機(jī)器也處在一個(gè)邊緣狀態(tài)的時(shí)候,這個(gè)增加的流量就會(huì)導(dǎo)致這臺(tái)機(jī)器也崩潰,最后導(dǎo)致整個(gè)集群不可用。
針對(duì)這個(gè)情況,Sentinel 提供了對(duì)應(yīng)的保護(hù)機(jī)制,讓系統(tǒng)的入口流量和系統(tǒng)的負(fù)載達(dá)到一個(gè)平衡,保證系統(tǒng)在能力范圍之內(nèi)處理最多的請(qǐng)求。
6、Sentinel 是如何工作的
Sentinel 的主要工作機(jī)制如下:
對(duì)主流框架提供適配或者顯示的 API,來(lái)定義需要保護(hù)的資源,并提供設(shè)施對(duì)資源進(jìn)行實(shí)時(shí)統(tǒng)計(jì)和調(diào)用鏈路分析。
根據(jù)預(yù)設(shè)的規(guī)則,結(jié)合對(duì)資源的實(shí)時(shí)統(tǒng)計(jì)信息,對(duì)流量進(jìn)行控制。同時(shí),Sentinel 提供開放的接口,方便您定義及改變規(guī)則。
Sentinel 提供實(shí)時(shí)的監(jiān)控系統(tǒng),方便您快速了解目前系統(tǒng)的狀態(tài)。
7、競(jìng)品對(duì)比

六、SpringBoot整合sentinel
1、加入pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
2、編寫sentinel規(guī)則
@PostConstruct
public void initFlowRules(){
//1.創(chuàng)建存放限流規(guī)則的集合
List<FlowRule> rules = new ArrayList<>();
//2.創(chuàng)建限流規(guī)則
FlowRule rule = new FlowRule();
//定義資源,表示sentinel會(huì)對(duì)這個(gè)資源生效
rule.setResource("helloSentinel");
//定義限流規(guī)則類型
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//定義QPS每秒能通過的請(qǐng)求個(gè)數(shù)
rule.setCount(2);
//3.將限流規(guī)則放入集合中
rules.add(rule);
//4.加載限流規(guī)則
FlowRuleManager.loadRules(rules);
}
@GetMapping("/helloSentinel")
public String hello(){
try{
Entry entry = SphU.entry("helloSentinel");
return "helloSentinel success.";
}catch (Exception e){
log.error(e.getMessage());
return "helloSentinel error";
}
}
3、測(cè)試
(1)頻率小于1秒兩次時(shí),訪問成功

(2)頻率大于1秒兩次時(shí),由于限流規(guī)則的設(shè)立,故失敗

七、springboot整合sentinel dashboard
1、安裝sentinel dashboard
(1)下載jar包
sentinel-1.7.1jar包下載鏈接
鏈接: https://pan.baidu.com/s/1MSwFNSaE_3gRxe6nsNXNDQ
提取碼: e5j2?
(2)啟動(dòng)jar包
java -Dserver.port=9000 -jar sentinel-dashboard.jar

2、springboot整合sentinel dashboard
(1)引入pom
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.7.2</version>
</dependency>
(2)配置啟動(dòng)類
-Dcsp.sentinel.dashboard.server=localhost:9000 -Dproject.name=GooReeyProject

(3)通過調(diào)用接口,使其在dashboard顯示出來(lái)

3、用sentinel dashboard配置流控
(1)注釋掉代碼中的流控設(shè)置代碼
(2)用控制臺(tái)的配置取代代碼

八、sentinel中其它定義資源的方式
1、拋出異常的方式定義資源
@GetMapping("/helloSentinel")
public String hello(){
try{
Entry entry = SphU.entry("helloSentinel");
return "helloSentinel success.";
}catch (Exception e){
log.error(e.getMessage());
return "helloSentinel error";
}
}
2、返回布爾值方式定義資源
代碼示例:
@GetMapping("/sentinelBoolean")
public boolean sentinelBoolean(){
if(SphO.entry("sentinelBoolean")){
try {
log.info("sentinelBoolean success.");
return true;
}finally {
SphO.exit();
}
}else{
log.warn("sentinelBoolean error.");
return false;
}
}

3、sentinel支持異步調(diào)用鏈路的統(tǒng)計(jì)
在異步調(diào)用中,需要通過SphU.asynvEntry(xxx)方法定義資源,并通常需要在異步的回調(diào)函數(shù)中調(diào)用exit()方法。
代碼編寫:
(1)啟動(dòng)類加入@EnableAsync注解
@EnableDiscoveryClient
@SpringBootApplication(scanBasePackages = "com.guor")
@MapperScan("com.guor.management.dao")
@RefreshScope
@EnableAsync
public class ManagementApplication {
public static void main(String[] args) {
SpringApplication.run(ManagementApplication.class, args);
}
}
(3)控制層
@GetMapping("/sentinelAsync")
public void sentinelAsync(){
AsyncEntry asyncEntry = null;
try {
asyncEntry = SphU.asyncEntry("sentinelAsync");
userService.sentinelAsync();
log.info("sentinelAsync success.");
}catch (BlockException e){
log.error("sentinelAsync error.");
}finally {
if(asyncEntry != null){
asyncEntry.exit();
}
}
}
sentinel dashboard未定義時(shí):

sentinel dashboard定義后:流控成功!

4、注解形式定義資源
(1)pom文件
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.7.2</version>
</dependency>
(2)配置類
package com.guor.management.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
@Configuration
public class SentinelAspectConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect(){
return new SentinelResourceAspect();
}
}
(3)控制類
@SentinelResource(value = "sentinel_Annotation", blockHandler = "exceptionHandler")
@GetMapping("/annotation")
public String sentinelAnnotation(){
return "sentinelAnnotation";
}
public String exceptionHandler(BlockException e){
e.printStackTrace();
return "系統(tǒng)繁忙,請(qǐng)稍后";
}
(4)定義流控規(guī)則

到此這篇關(guān)于Spring?Boot整合流控組件Sentinel的文章就介紹到這了,更多相關(guān)Spring?Boot流控組件Sentinel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
搭建Spring Boot聚合項(xiàng)目的實(shí)現(xiàn)示例
本文主要介紹了搭建Spring Boot聚合項(xiàng)目的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
Java圖形化界面設(shè)計(jì)之容器(JFrame)詳解
這篇文章主要介紹了Java圖形化界面設(shè)計(jì)之容器(JFrame)詳解,條理清晰,依次介紹了Java基本類(JFC),AWT和Swing的區(qū)別,Swing基本框架,圖形化設(shè)計(jì)步驟以及組件容器的使用等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
Java中Bean轉(zhuǎn)Map問題歸納總結(jié)
Java Bean轉(zhuǎn)Map的坑很多,最常見的就是類型丟失和屬性名解析錯(cuò)誤的問題,下面這篇文章主要給大家介紹了關(guān)于Java中Bean轉(zhuǎn)Map問題歸納總結(jié)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
SpringBoot集成企業(yè)微信開發(fā)的實(shí)現(xiàn)
本文將詳細(xì)介紹如何使用?Spring?Boot?集成企業(yè)微信開發(fā),通過企業(yè)微信?API?可以實(shí)現(xiàn)企業(yè)內(nèi)部的一些自動(dòng)化業(yè)務(wù)流程,提高工作效率,感興趣的可以了解一下2023-07-07
圖解Spring Security 中用戶是如何實(shí)現(xiàn)登錄的
這篇文章主要介紹了圖解Spring Security 中用戶是如何實(shí)現(xiàn)登錄的,文中通過示例代碼和圖片介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

