Spring?Cloud?Sentinel快速入門步驟
在企業(yè)級微服務開發(fā)中,Sentinel 解決的是系統(tǒng)穩(wěn)定性問題。
一、Sentinel 核心概念與目標
Sentinel(分布式系統(tǒng)的流量防衛(wèi)兵)是阿里巴巴開源的一套面向分布式服務架構(gòu)的流量控制、熔斷降級、系統(tǒng)負載保護的組件。
它的核心目的是保護應用,確保服務在面對高并發(fā)、突發(fā)流量或依賴服務不可用時,仍能保持高可用性和穩(wěn)定性,避免因局部故障導致整個系統(tǒng)雪崩。
1-1. 核心概念
| 概念 | 描述 | 作用 |
| 資源 (Resource) | Sentinel 中最核心的概念??梢允侨魏文MWo的代碼塊、服務、方法、接口等。用唯一名稱標識。 | 定義流量防護的目標。 |
| 規(guī)則 (Rule) | 為資源定義的具體保護措施,如流量閾值、降級策略等。 | 定義如何保護資源(限流、降級、系統(tǒng)保護)。 |
| Slot Chain | Sentinel 的核心處理鏈。當請求流經(jīng)資源時,會依次經(jīng)過統(tǒng)計、限流、熔斷等各個 Slot(插槽)進行處理。 | Sentinel 工作的底層機制。 |
1-2、流量防護三大核心功能:
Sentinel 提供了三大保護功能,都基于對資源的實時統(tǒng)計。
1. ?? 流量控制 (Flow Control)
這是 Sentinel 最基本也是最重要的功能,目的是控制對資源的請求速度,確保其不超過系統(tǒng)的處理能力。
- 指標: 通常基于 QPS(每秒查詢數(shù))或并發(fā)線程數(shù)。
- 示例規(guī)則: 資源
getProductInfo的 QPS 閾值為 200,當超過 200 QPS 時,后續(xù)請求將被拒絕(默認是FailFast策略)。
2. ? 熔斷降級 (Degrade)
當依賴的資源或服務不穩(wěn)定(響應慢或失敗率高)時,Sentinel 會自動切斷調(diào)用(熔斷),讓請求快速失敗,而不是繼續(xù)堆積,避免拖垮自身服務。
- 策略:
- 慢調(diào)用比例 (RT): 當資源的平均響應時間(RT)超過某個閾值,并且請求量也達到一定值時,觸發(fā)熔斷。
- 異常比例: 當資源的異常請求比例達到閾值時,觸發(fā)熔斷。
- 異常數(shù): 在一個時間窗口內(nèi),異常請求總數(shù)達到閾值時,觸發(fā)熔斷。
- 熔斷器狀態(tài): 正常 -> 打開 (Open) -> 半開 (Half-Open) -> 正常。熔斷打開后,在設定的恢復時間窗后進入半開狀態(tài)嘗試放行少量請求。
3. ??? 系統(tǒng)保護 (System Protection)
從整個系統(tǒng)的維度進行負載保護,而不是針對單個資源。它基于系統(tǒng)的整體負載指標(如 CPU 利用率、系統(tǒng) Load、平均 RT 等)進行判斷和限流。
- 作用: 防止系統(tǒng)壓力過大時,雪崩式地拒絕所有請求,保護核心業(yè)務,同時保證非核心業(yè)務的快速失敗。
二、Sentinel 快速入門步驟(基于 Spring Cloud/SpringBoot)
步驟一:部署 Sentinel Dashboard (TC)
Sentinel 的規(guī)則和監(jiān)控信息通常通過控制臺(Dashboard)來配置和查看。
- 下載: 從 Sentinel GitHub 或 Maven Central 下載最新的
sentinel-dashboard.jar。 - 啟動: 運行 Dashboard。默認端口是
8080。 java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard.jar
- 訪問: 瀏覽器訪問
http://localhost:8080,默認賬號/密碼是sentinel/sentinel。
步驟二:集成到業(yè)務微服務
引入依賴: 在需要進行流量防護的微服務中引入 Sentinel 依賴(推薦使用 Spring Cloud Alibaba 提供的 starter)。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>配置客戶端: 在 application.properties 或 application.yml 中配置服務名和 Dashboard 地址。
# application.yml
spring:
application:
name: your-service-name
# 配置 Sentinel Dashboard 地址
cloud:
sentinel:
transport:
dashboard: localhost:8080定義資源 (Resource):
import com.alibaba.csp.sentinel.annotation.SentinelResource;
@Service
public class OrderService {
// 使用 @SentinelResource 保護方法
@SentinelResource(value = "createOrder",
blockHandler = "handleBlock", // 違背限流/降級規(guī)則時調(diào)用的方法
fallback = "handleFallback") // 業(yè)務異常時調(diào)用的方法
public String createOrder(String userId) {
// 核心業(yè)務邏輯
return "Order created successfully";
}
// 限流或降級時的處理邏輯(參數(shù)要匹配原方法)
public String handleBlock(String userId, BlockException ex) {
System.out.println("Blocked by Sentinel: " + ex.getMessage());
return "System busy, please try later.";
}
// 業(yè)務異常時的處理邏輯(Throwable 參數(shù))
public String handleFallback(String userId, Throwable ex) {
System.out.println("Service logic error: " + ex.getMessage());
return "Internal error occurred.";
}
}- 自動定義 (Automatic): Sentinel 會自動將 HTTP 接口、Feign 客戶端調(diào)用、Dubbo 接口等識別為資源。
- 手動定義 (Manual): 使用
@SentinelResource注解來保護您代碼中的關鍵業(yè)務邏輯。 - 配置規(guī)則:
- 啟動您的微服務并調(diào)用幾次被
@SentinelResource保護的方法。(懶加載) - 登錄 Sentinel Dashboard,在左側(cè)菜單找到您的服務。
- 進入 簇點鏈路 找到您定義的資源(如
createOrder),然后點擊右側(cè)的 新增限流 或 新增降級 規(guī)則。
- 啟動您的微服務并調(diào)用幾次被
- 例如: 設置
createOrder的 QPS 閾值 為 10,流控模式 為 快速失敗 (Fail Fast)。
企業(yè)級最佳實踐
- 持久化規(guī)則: Dashboard 配置的規(guī)則默認只存在內(nèi)存中,重啟后丟失。企業(yè)級應用必須將規(guī)則持久化到配置中心(如 Nacos、Apollo),以確保規(guī)則的動態(tài)性和持久性。
- 區(qū)分降級和限流處理:
blockHandler:處理 Sentinel 規(guī)則 導致的異常(限流、降級、系統(tǒng)保護)。fallback:處理 業(yè)務代碼 執(zhí)行時拋出的異常(如數(shù)據(jù)庫連接失敗、空指針等)。
- 統(tǒng)一入口: 對外部提供的 API Gateway 接口是最重要的限流資源,應優(yōu)先配置保護。
三、@SentinelResource一般是加在哪里?
@SentinelResource是Sentinel的限流降級注解。
3-1、加在哪里
1. Service層方法(最常見)
@Service
public class OrderService {
@SentinelResource(
value = "createOrder",
blockHandler = "handleCreateOrderBlock",
fallback = "createOrderFallback"
)
public Order createOrder(Order order) {
// 業(yè)務邏輯
return orderMapper.insert(order);
}
// 處理限流(BlockException)
public Order handleCreateOrderBlock(Order order, BlockException e) {
log.warn("訂單創(chuàng)建被限流了");
return null;
}
// 處理熔斷降級(業(yè)務異常)
public Order createOrderFallback(Order order, Throwable e) {
log.warn("訂單創(chuàng)建失敗,執(zhí)行降級方案");
return new Order(); // 返回默認值
}
}2. Controller層方法
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping
@SentinelResource(
value = "createOrderApi",
blockHandler = "handleBlock"
)
public ApiResponse<Order> createOrder(@RequestBody Order order) {
Order result = orderService.createOrder(order);
return ApiResponse.success(result);
}
public ApiResponse<Order> handleBlock(Order order, BlockException e) {
return ApiResponse.fail("系統(tǒng)繁忙,請稍后再試");
}
}3. Feign客戶端方法
@FeignClient(name = "stock-service", fallback = StockServiceFallback.class)
public interface StockServiceClient {
@PostMapping("/api/stock/deduct")
@SentinelResource(
value = "deductStock",
fallback = "deductStockFallback"
)
Stock deductStock(@RequestParam Long productId, @RequestParam Integer quantity);
default Stock deductStockFallback(Long productId, Integer quantity) {
log.warn("庫存服務調(diào)用失敗,執(zhí)行降級");
return new Stock();
}
}4. 異步方法
@Service
public class AsyncOrderService {
@Async
@SentinelResource(
value = "asyncProcessOrder",
blockHandler = "handleAsyncBlock"
)
public void processOrderAsync(Order order) {
// 異步處理邏輯
doSomeHeavyWork(order);
}
public void handleAsyncBlock(Order order, BlockException e) {
log.warn("異步處理被限流");
}
}3-2、一般不加的地方
? 不加在Mapper層
// 錯誤示范
@Mapper
public interface OrderMapper {
@SentinelResource("selectOrder") // ? 不要加這兒
Order selectById(Long id);
}
// 原因:
// 1. Mapper直接操作數(shù)據(jù)庫,沒有業(yè)務邏輯
// 2. 限流應該在業(yè)務層面
// 3. 多個Service可能調(diào)用同一個Mapper? 不加在private私有方法
@Service
public class OrderService {
@SentinelResource("privateMethod") // ? 不要加
private void privateMethod() {
// ...
}
// 原因:Sentinel是通過代理實現(xiàn)的,私有方法代理不了
}? 不加在構(gòu)造方法
@Service
public class OrderService {
@SentinelResource("constructor") // ? 不要加
public OrderService() {
// ...
}
}? 不加在static方法
@Service
public class OrderService {
@SentinelResource("staticMethod") // ? 不要加
public static void staticMethod() {
// ...
}
// 原因:static方法不能被代理
}3-3、最佳實踐
推薦做法:Service + Controller雙層
// ===== Controller層 =====
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@SentinelResource(
value = "createOrderApi", // API級別的限流
blockHandler = "apiBlockHandler"
)
@PostMapping
public ApiResponse<Order> createOrder(@RequestBody Order order) {
return ApiResponse.success(orderService.createOrder(order));
}
public ApiResponse<Order> apiBlockHandler(Order order, BlockException e) {
return ApiResponse.fail("API請求過于頻繁");
}
}
// ===== Service層 =====
@Service
public class OrderService {
@SentinelResource(
value = "createOrderService", // 業(yè)務級別的限流
blockHandler = "serviceBlockHandler",
fallback = "createOrderFallback"
)
public Order createOrder(Order order) {
// 實際業(yè)務邏輯
return orderMapper.insert(order);
}
public Order serviceBlockHandler(Order order, BlockException e) {
return null; // 限流處理
}
public Order createOrderFallback(Order order, Throwable e) {
return new Order(); // 降級處理
}
}為什么雙層?
用戶請求
↓
Controller層(@SentinelResource)
├─ 控制HTTP請求的流量
├─ 返回友好的錯誤信息
└─ 保護系統(tǒng)入口
↓
Service層(@SentinelResource)
├─ 控制業(yè)務操作的流量
├─ 保護核心業(yè)務邏輯
└─ 其他Service也可能調(diào)用3-4、@SentinelResource 注解參數(shù)說明
@SentinelResource(
value = "createOrder", // 資源名,必需
blockHandler = "handleBlock", // 限流/降級時的處理方法
blockHandlerClass = BlockHandlers.class, // 指定外部類
fallback = "fallbackMethod", // 業(yè)務異常時的降級方法
fallbackClass = FallbackMethods.class, // 指定外部類
exceptionsToIgnore = {IOException.class} // 忽略的異常
)
public Order createOrder(Order order) {
// ...
}3-5、常見場景總結(jié)
| 場景 | 位置 | 用途 |
|---|---|---|
| 保護HTTP接口 | Controller | 限制請求頻率 |
| 保護業(yè)務方法 | Service | 限制業(yè)務操作 |
| 遠程調(diào)用降級 | Feign客戶端 | 調(diào)用失敗降級 |
| 異步任務保護 | @Async方法 | 限制異步線程 |
| 定時任務保護 | @Scheduled方法 | 限制定時任務 |
簡單總結(jié):加在Service和Controller的public業(yè)務方法上,不要加在Mapper、私有方法、static方法。
到此這篇關于Spring Cloud Sentinel入門講解的文章就介紹到這了,更多相關Spring Cloud Sentinel入門內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
shiro與spring?security用自定義異常處理401錯誤
這篇文章主要介紹了shiro與spring?security用自定義異常處理401錯誤,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
Spring Cloud zuul自定義統(tǒng)一異常處理實現(xiàn)方法
這篇文章主要介紹了Spring Cloud zuul自定義統(tǒng)一異常處理實現(xiàn),需要的朋友可以參考下2018-02-02
基于@Value注解和@ConfigurationProperities注解的區(qū)別及說明
本文主要介紹了Spring?Boot中三種配置屬性的注入方式:@Value、Environment對象和@ConfigurationProperties,通過這些方式,可以方便地將配置文件中的屬性值綁定到Spring管理的Bean對象的屬性上,從而實現(xiàn)配置信息的動態(tài)加載2026-03-03
idea創(chuàng)建springboot項目,Application.java不能運行問題及解決
這篇文章主要介紹了idea創(chuàng)建springboot項目,Application.java不能運行問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
maven插件maven-assembly-plugin打包歸納文件zip/tar使用
java項目運行的文件需要jar或者war格式,同時還需要使用Java命令,本文主要介紹了maven插件maven-assembly-plugin打包歸納文件zip/tar使用,具有一定的參考價值,感興趣的可以了解一下2024-02-02
登陸驗證碼kaptcha結(jié)合spring boot的用法詳解
在一個web應用中驗證碼是一個常見的元素。不管是防止機器人還是爬蟲都有一定的作用,下面這篇文章主要給大家介紹了登陸驗證碼kaptcha結(jié)合spring boot用法的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-06-06
修改request的parameter的幾種方式總結(jié)
這篇文章主要介紹了修改request的parameter的幾種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
詳解Spring整合mybatis--Spring中的事務管理(xml形式)
這篇文章主要介紹了Spring整合mybatis--Spring中的事務管理(xml形式),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-11-11

