在分布式系統(tǒng)中剑梳,隨著服務(wù)的逐漸增多唆貌,穩(wěn)定性和容錯(cuò)性變得至關(guān)重要。為了保證系統(tǒng)的高可用性垢乙,限流锨咙、熔斷、降級(jí)等機(jī)制成為了開發(fā)者必不可少的工具追逮。
Sentinel 作為阿里巴巴開源的一款流量防護(hù)組件酪刀,為微服務(wù)提供了流量控制粹舵、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)蓖宦、實(shí)時(shí)監(jiān)控等功能齐婴,廣泛應(yīng)用于 Spring Cloud 和 Dubbo 生態(tài)中。
一稠茂、核心功能
1.流量控制:
- QPS限流:基于每秒請(qǐng)求數(shù)量進(jìn)行限流柠偶。
- 并發(fā)線程數(shù)限流:限制某個(gè)資源的并發(fā)訪問線程數(shù)。
- 閾值類型:包括直接拒絕睬关、排隊(duì)等待等诱担。
2.熔斷降級(jí):
- 響應(yīng)時(shí)間:根據(jù)資源的平均響應(yīng)時(shí)間來進(jìn)行熔斷。
- 異常比例:當(dāng)某個(gè)資源的異常比例達(dá)到設(shè)定閾值時(shí)电爹,觸發(fā)熔斷蔫仙。
- 異常數(shù):基于異常數(shù)量來觸發(fā)熔斷。
3.系統(tǒng)保護(hù):
- 根據(jù)系統(tǒng)的 Load 系數(shù)丐箩、CPU摇邦、線程數(shù)等自動(dòng)限流,確保系統(tǒng)處于健康狀態(tài)屎勘。
4.熱點(diǎn)參數(shù)限流:
- 根據(jù)請(qǐng)求參數(shù)的熱點(diǎn)值(如商品 ID)進(jìn)行流量限制施籍。
5.授權(quán)規(guī)則:
- 通過控制資源訪問權(quán)限來保護(hù)系統(tǒng)資源的一種規(guī)則。
二概漱、Spring Cloud 中集成 Sentinel
在 Spring Cloud 中集成 Sentinel 非常簡單丑慎,通過 Spring Cloud Alibaba 提供的自動(dòng)化配置,開發(fā)者可以快速在項(xiàng)目中引入 Sentinel 的保護(hù)機(jī)制瓤摧。
1. 添加 Maven 依賴
首先竿裂,在你的 Spring Cloud 項(xiàng)目的 pom.xml 中添加以下依賴:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-dubbo-adapter</artifactId>
<version>1.8.2</version>
</dependency>
2. 在 application.yml 中配置 Sentinel
配置文件中需要定義與 Sentinel 控制臺(tái)通信的配置,以及與 Dubbo 相關(guān)的基本配置:
spring:
application:
name: sentinel-demo
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制臺(tái)地址
port: 8719 # 服務(wù)與 Sentinel 控制臺(tái)的通信端口
filter:
enabled: true # 開啟 Sentinel 對(duì) Spring MVC 的保護(hù)照弥,默認(rèn)為 false
datasource:
# 自定義的規(guī)則名稱腻异,可以配置一種規(guī)則或多種規(guī)則進(jìn)行流控管理
ds1:
# 從nacos中取相應(yīng)的配置
nacos:
server-addr: localhost:8848 # Nacos 配置中心的地址
username: xxx # Nacos 配置中心的用戶名
password: xxx # Nacos 配置中心的密碼
namespace: xxx # Nacos 配置中心的命名空間
dataId: sentinel-rules # Nacos 配置中心中的配置文件 ID,可以統(tǒng)一使用一套产喉,也可以每個(gè)服務(wù)單獨(dú)配置捂掰,例如${spring.application.name}-sentinel-rules
groupId: DEFAULT_GROUP # 配置文件所屬的組
rule-type: flow # 規(guī)則類型為流量控制規(guī)則
data-type: json # 配置數(shù)據(jù)的格式為 JSON
ds2:
nacos:
server-addr: localhost:8848
username: xxx
password: xxx
namespace: xxx
dataId: degrade-rules # Nacos 配置中心中的配置文件 ID
groupId: DEFAULT_GROUP
rule-type: degrade # 規(guī)則類型為熔斷規(guī)則
data-type: json
ds3:
nacos:
server-addr: localhost:8848
username: xxx
password: xxx
namespace: xxx
dataId: system-rules # Nacos 配置中心中的配置文件 ID
groupId: DEFAULT_GROUP
rule-type: system # 規(guī)則類型為系統(tǒng)規(guī)則
data-type: json
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://localhost:2181 # 注冊(cè)中心地址,使用 Zookeeper
protocol:
name: dubbo # 協(xié)議名稱
port: 20880 # Dubbo 服務(wù)端口
三曾沈、Dubbo RPC 接口的限流與熔斷配置
1. 創(chuàng)建 Dubbo 服務(wù)接口及實(shí)現(xiàn)類
接下來,創(chuàng)建一個(gè) Dubbo 服務(wù)接口和實(shí)現(xiàn)類鸥昏,并使用 @SentinelResource 注解來配置限流和熔斷策略塞俱。
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.apache.dubbo.config.annotation.DubboService;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public interface GreetingService {
String greet(String name); // 定義服務(wù)接口方法
}
@DubboService // 聲明 Dubbo 服務(wù)
public class GreetingServiceImpl implements GreetingService {
@Override
@SentinelResource(value = "greet", blockHandler = "handleBlock")
public String greet(String name) {
// 業(yè)務(wù)邏輯代碼,返回問候語
return "Hello, " + name;
}
// 限流或熔斷時(shí)的處理方法
public String handleBlock(String name, BlockException ex) {
// 當(dāng)觸發(fā)限流或熔斷時(shí)吏垮,返回的處理信息
return "Request blocked: " + ex.getClass().getSimpleName();
}
}
在這個(gè)示例中障涯,@SentinelResource 注解的 value 屬性指定了資源名稱為 greet罐旗,并且指定了當(dāng)限流或熔斷時(shí)調(diào)用的處理方法 handleBlock。
2. 通過 Sentinel 控制臺(tái)配置限流規(guī)則
Sentinel 控制臺(tái)可以方便地管理和配置流控規(guī)則唯蝶。
-
啟動(dòng) Sentinel 控制臺(tái):下載并啟動(dòng) Sentinel 控制臺(tái) JAR 包九秀。
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard.jar
-
訪問控制臺(tái)并配置規(guī)則:登錄 Sentinel 控制臺(tái),選擇你的應(yīng)用并添加流控規(guī)則粘我。
資源名:greet (與 @SentinelResource 中的 value 值一致)
限流模式:QPS
限流閾值:例如設(shè)置為 10鼓蜒,表示當(dāng) greet 方法的每秒請(qǐng)求超過 10 次時(shí),觸發(fā)限流征字。
四都弹、測試限流與熔斷效果
1. 啟動(dòng)項(xiàng)目并測試
啟動(dòng)你的 Spring Cloud 項(xiàng)目,使用 Dubbo 客戶端進(jìn)行 RPC 調(diào)用匙姜。當(dāng)并發(fā)請(qǐng)求超過設(shè)定的限流閾值時(shí)畅厢,將觸發(fā)限流,客戶端將收到 handleBlock 方法返回的信息氮昧。
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@DubboReference(version = "1.0.0")
private GreetingService greetingService; // 引用 Dubbo 服務(wù)
@GetMapping("/greet")
public String greet(String name) {
// 調(diào)用 Dubbo 服務(wù)的 greet 方法
return greetingService.greet(name);
}
}
訪問 http://localhost:8080/greet?name=World框杜,當(dāng)訪問頻率過高時(shí),應(yīng)該會(huì)收到 Request blocked 的返回信息袖肥。
五咪辱、Controller 方法的限流與熔斷配置
Sentinel 也可以對(duì) Spring Boot 項(xiàng)目中的 Controller 方法進(jìn)行限流,其使用方式與Dubbo接口限流的方式基本一致昭伸。
@RestController
public class TestController {
@GetMapping("/test")
@SentinelResource(value = "testResource", blockHandler = "handleBlock")
public String test() {
return "Hello Sentinel!";
}
public String handleBlock(BlockException ex) {
return "Request blocked due to flow control";
}
}
六梧乘、通過 Nacos 動(dòng)態(tài)管理限流規(guī)則
為了更靈活地管理和調(diào)整限流規(guī)則,可以通過 Nacos 配置中心實(shí)現(xiàn)規(guī)則的動(dòng)態(tài)管理庐杨。
1.在 Nacos 中創(chuàng)建配置文件
登錄 Nacos 控制臺(tái)选调,創(chuàng)建一個(gè)新的配置文件sentinel-rules,內(nèi)容如下:
[
{
"resource": "greet", //資源名稱
"limitApp": "default", // 限制應(yīng)用灵份,default 表示對(duì)所有應(yīng)用生效
"grade": 1, // 限流閾值類型仁堪,0表示線程數(shù),1表示QPS
"count": 10, // 閾值
"strategy": 0, // 流控模式填渠,0表示直接弦聂,1表示關(guān)聯(lián),2表示鏈路
"controlBehavior": 0, // 流控效果氛什,0表示快速失敗莺葫,1表示W(wǎng)arm Up,2表示排隊(duì)等待(Warm Up 是指一種流控策略枪眉,中文通常翻譯為“預(yù)熱”或“暖備”捺檬。具體來說,Warm Up 機(jī)制用于在系統(tǒng)在一定時(shí)間內(nèi)逐漸增加流量閾值贸铜,而不是立即將流量限制在最大閾值上堡纬,以防止系統(tǒng)在剛開始承受高流量時(shí)出現(xiàn)負(fù)載過大的情況聂受。)
"warmUpPeriodSec": 10, // Warm Up 時(shí)長,單位為秒
"maxQueueingTimeMs": 500 // 排隊(duì)等待最大時(shí)長烤镐,單位為毫秒
}
]
2.動(dòng)態(tài)加載規(guī)則
配置完成后蛋济,Sentinel 會(huì)自動(dòng)從 Nacos 拉取最新的規(guī)則并應(yīng)用到系統(tǒng)中。
七炮叶、其他規(guī)則類型
Sentinel 提供了五種主要的規(guī)則配置:流量控制規(guī)則碗旅、降級(jí)規(guī)則、系統(tǒng)規(guī)則悴灵、熱點(diǎn)參數(shù)規(guī)則和授權(quán)規(guī)則扛芽。每種規(guī)則都有其特定的配置項(xiàng)。剛才已經(jīng)使用過流量控制規(guī)則积瞒,下面介紹其它四種規(guī)則川尖。
降級(jí)規(guī)則配置(Degrade Rules)
降級(jí)規(guī)則用于熔斷降級(jí),當(dāng)請(qǐng)求的錯(cuò)誤率或響應(yīng)時(shí)間超過設(shè)定的閾值時(shí)茫孔,可以觸發(fā)降級(jí)(所以沒有controlBehavior配置)叮喳。
基本配置項(xiàng):
spring:
cloud:
sentinel:
datasource:
degrade:
nacos:
server-addr: localhost:8848
dataId: degrade-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: degrade
規(guī)則內(nèi)容(JSON 格式)
[
{
"resource": "exampleResource", // 資源名稱
"grade": 1, // 熔斷策略,0表示慢調(diào)用比例缰贝,1表示異常比例馍悟,2表示異常數(shù)
"count": 1000, // 閾值(當(dāng) grade=0 時(shí)為 RT,單位為 ms剩晴;當(dāng) grade=1 時(shí)為異常比例锣咒;當(dāng) grade=2 時(shí)為異常數(shù))
"timeWindow": 10, // 熔斷持續(xù)時(shí)間,單位為秒
"minRequestAmount": 5, // 最小請(qǐng)求數(shù)
"statIntervalMs": 1000 // 統(tǒng)計(jì)時(shí)長赞弥,單位為毫秒
}
]
系統(tǒng)規(guī)則配置(System Rules)
系統(tǒng)規(guī)則用于全局的系統(tǒng)保護(hù)毅整,防止整個(gè)系統(tǒng)因資源超載而崩潰。當(dāng)觸發(fā)系統(tǒng)規(guī)則的某一項(xiàng)(如 QPS绽左、線程數(shù)悼嫉、CPU 使用率等)達(dá)到設(shè)定的閾值時(shí),Sentinel 會(huì)直接拒絕新進(jìn)入的請(qǐng)求拼窥。
基本配置項(xiàng)
spring:
cloud:
sentinel:
datasource:
system:
nacos:
server-addr: localhost:8848
dataId: system-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: system
規(guī)則內(nèi)容(JSON 格式)
[
{
"avgRt": 1000, // 全局平均響應(yīng)時(shí)間閾值戏蔑,單位為毫秒
"maxThread": 20, // 全局最大線程數(shù)
"qps": 500, // 全局QPS閾值
"cpuUsage": 0.8, // 全局CPU使用率閾值,取值范圍 0.0-1.0
"highestSystemLoad": 5 // 系統(tǒng)負(fù)載閾值鲁纠,僅在 Linux/Unix 上生效
}
]
熱點(diǎn)參數(shù)規(guī)則配置(Hot Param Rules)
熱點(diǎn)參數(shù)規(guī)則用于限制某個(gè)資源的某個(gè)參數(shù)的熱點(diǎn)頻次总棵,防止某個(gè)特定參數(shù)(如用戶ID)過熱。
基本配置項(xiàng)
spring:
cloud:
sentinel:
datasource:
param-flow:
nacos:
server-addr: localhost:8848
dataId: param-flow-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: param-flow
規(guī)則內(nèi)容(JSON 格式)
[
{
"resource": "exampleResource", // 資源名稱
"paramIdx": 0, // 參數(shù)索引改含,指定對(duì)第幾個(gè)參數(shù)進(jìn)行限流彻舰,從 0 開始
"count": 100, // 限流閾值
"grade": 1, // 限流等級(jí),1表示QPS
"controlBehavior": 0, // 控制行為候味,0表示快速失敗刃唤,1表示W(wǎng)arm Up,2表示排隊(duì)等待
"paramFlowItemList": [
{
"object": "exampleValue", // 參數(shù)值
"classType": "java.lang.String", // 參數(shù)類型
"count": 10 // 對(duì)應(yīng)的限流閾值
}
]
}
]
授權(quán)規(guī)則配置(Authority Rule)
授權(quán)規(guī)則是通過控制資源訪問權(quán)限來保護(hù)系統(tǒng)資源的一種規(guī)則白群。它主要用于防止非法用戶或未授權(quán)的請(qǐng)求訪問指定資源尚胞,從而提供更加精細(xì)的安全管理。
基本配置項(xiàng)
spring:
cloud:
sentinel:
datasource:
param-flow:
nacos:
server-addr: localhost:8848
dataId: authority-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: authority
規(guī)則內(nèi)容(JSON 格式)
[
{
"resource": "testApi",
"limitApp": "appA",
"strategy": 0 // 白名單模式
},
{
"resource": "testApi",
"limitApp": "appB",
"strategy": 1 // 黑名單模式
}
]
八帜慢、與Hystrix的差異
Sentinel 和 Hystrix 是用于實(shí)現(xiàn)熔斷笼裳、限流和容錯(cuò)處理的兩個(gè)常用工具。盡管它們?cè)诠δ苌嫌幸恍┲丿B粱玲,但它們?cè)谠O(shè)計(jì)理念躬柬、功能特點(diǎn)和應(yīng)用場景上有許多不同之處。以下是 Sentinel 和 Hystrix 的主要不同點(diǎn):
設(shè)計(jì)理念
Sentinel
- Sentinel 的設(shè)計(jì)理念是“全方位流量防護(hù)”抽减。它不僅關(guān)注熔斷和降級(jí)允青,還涵蓋了流量控制、熱點(diǎn)參數(shù)限流卵沉、系統(tǒng)保護(hù)等多個(gè)維度颠锉,旨在提供全方位的流量管理和系統(tǒng)保護(hù)。
Hystrix
- Hystrix 的設(shè)計(jì)理念是“防止服務(wù)之間的故障傳播”史汗。它專注于熔斷琼掠、降級(jí)和線程隔離,通過這些手段防止單個(gè)服務(wù)的故障擴(kuò)散到整個(gè)系統(tǒng)停撞。
社區(qū)狀態(tài)
Sentinel
- 活躍開發(fā):Sentinel 由阿里巴巴開源瓷蛙,社區(qū)非常活躍戈毒,定期發(fā)布更新和新功能艰猬,特別是在國內(nèi)有廣泛的使用和支持。
Hystrix
- 進(jìn)入維護(hù)狀態(tài):Hystrix 由 Netflix 開源副硅,但目前已經(jīng)進(jìn)入維護(hù)狀態(tài)姥宝,不再積極開發(fā)新功能。Netflix 也推薦開發(fā)者轉(zhuǎn)向其他替代方案恐疲,如 Resilience4j腊满。
性能開銷
Sentinel
- 輕量級(jí):Sentinel 在流控和熔斷的實(shí)現(xiàn)上相對(duì)輕量,具有較高的性能培己,特別適合高并發(fā)場景碳蛋。
Hystrix
- Hystrix 的線程池隔離機(jī)制雖然有效,但也帶來了一定的性能開銷省咨,尤其是在高并發(fā)場景下肃弟,可能會(huì)出現(xiàn)線程池耗盡的問題。
總的來說,Sentinel 是一個(gè)功能全面笤受、擴(kuò)展性強(qiáng)穷缤、適合復(fù)雜場景的流控和熔斷解決方案,特別適用于需要多維度保護(hù)和實(shí)時(shí)動(dòng)態(tài)調(diào)整的系統(tǒng)箩兽。
而 Hystrix 則專注于熔斷和降級(jí)津肛,適合簡單的容錯(cuò)需求,但由于已進(jìn)入維護(hù)狀態(tài)汗贫,可能不適合長期使用或新項(xiàng)目的開發(fā)身坐。
總結(jié)
Sentinel 為微服務(wù)架構(gòu)中的限流、熔斷等容錯(cuò)機(jī)制提供了強(qiáng)大的支持落包。通過在 Spring Cloud 中集成 Sentinel部蛇,可以輕松實(shí)現(xiàn)對(duì)服務(wù)的流量控制和穩(wěn)定性保障。
通過合理地配置和使用 Sentinel咐蝇,可以顯著提高分布式系統(tǒng)的穩(wěn)定性和容錯(cuò)能力涯鲁,確保在高并發(fā)場景下系統(tǒng)依然能夠平穩(wěn)運(yùn)行。