
大家好,我是哪吒。
Sentinel是阿里巴巴開源的一款輕量級流量控制、熔斷降級工具,它提供了實時的流量控制,熔斷降級等功能,能夠幫助我們實現服務的高可用性和穩定性。
本文將會介紹Sentinel的作用和優勢、快速開始、進階使用、Spring Cloud Alibaba Sentinel整合以及實踐案例,并對Sentinel的局限和不足進行分析。
一、前言
1、關于 Sentinel
Sentinel 是阿里巴巴開源的一款針對分布式系統的流量控制、熔斷降級的框架。在微服務架構的系統中,請求流量復雜多樣,可能會因為某一個服務異常而導致整體服務不可用,這時候需要熔斷降級,而 Sentinel 就提供了這樣的解決方案。

2、Sentinel 的作用和優勢
Sentinel 可以針對服務方法調用、HTTP 請求、Dubbo 服務等,進行實時的流量控制、熔斷降級,確保服務高可用,同時還可以提供實時的監控和報警功能。
Sentinel 有以下一些優勢:
- 豐富的應用場景和細粒度的控制: Sentinel 支持多種應用場景,包括熔斷降級、流量控制、系統保護、熱點參數限流等,而且可以實現細粒度的控制;
- 強大的實時監測機制: Sentinel 提供了實時的監測、報警機制,能夠對系統運行情況進行實時檢測和通知,發現問題更加及時;
- 易于擴展: Sentinel 為開發者提供了簡單易用的擴展接口,開發者可以方便的實現自定義的控制和監測邏輯;
- 易于集成: Sentinel 支持多種開發框架,包括 Spring Cloud、Dubbo、Feign 等,開發者可以很方便的將 Sentinel 集成到自己的應用中;
3、本文目的和內容概述
本文將為讀者介紹 Sentinel 的基礎和進階使用方法,包括
- 如何配置 Sentinel 控制臺;
- 如何編寫并測試 Sentinel 規則、如何使用自定義 Sentinel 規則擴展開發;
- 介紹 Sentinel 和 Spring Cloud Alibaba 的整合方法,并且給出了一些 Sentinel 實踐案例供讀者參考。
本文的目的是幫助讀者快速上手使用 Sentinel,并且深入理解其基本原理和使用方法。同時,也希望能夠對讀者們的日常工作有所幫助。
二、快速開始
1、環境準備
在開始使用 Sentinel 之前,我們需要準備好以下環境:
- JDK 1.8 或更高版本
- Maven 3.0 或更高版本
- Sentinel-dashboard
2、引入 Sentinel 依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
3、配置 Sentinel 控制臺
在Sentinel的官網下載最新的控制臺jar包,然后在控制臺目錄下執行以下命令啟動控制臺:
java -jar sentinel-dashboard-1.8.2.jar
啟動成功后,可以通過瀏覽器訪問http://localhost:8080/#/dashboard/home查看控制臺頁面。
4、注冊應用到 Sentinel 控制臺
在應用啟動類上添加注解@EnableSentinel注解,然后在配置文件中配置應用名稱和Sentinel控制臺的地址:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: sentinel
groupId: DEFAULT_GROUP
data-type: json
5、編寫并測試 Sentinel 規則
Sentinel提供了多種限流降級策略,本文以流控規則為例進行演示。
在需要限流的方法上添加@SentinelResource注解,然后配置流控規則:
@GetMapping("/hello")
@SentinelResource(value = "hello", blockHandler = "blockHandler")
public String hello() {
return "Hello, World!";
}
public String blockHandler(BlockException e) {
return "請求過于頻繁,請稍后重試!";
}
在控制臺的流控規則頁面添加對應的規則,設置好閾值和統計窗口等參數,然后測試該接口。
三、進階使用
1、Sentinel Dashboard 使用詳解
Sentinel Dashboard是Sentinel的可視化監控平臺,可以用于實時監控應用的流量、延遲、異常等指標,并對應用進行限流降級等操作。

Sentinel客戶端首先向Sentinel Dashboard注冊。Sentinel Dashboard返回一個token給客戶端,客戶端將使用該token連接Sentinel。
應用程序將使用token連接Sentinel,Sentinel客戶端將返回連接成功信息。Sentinel客戶端將實時推送metrics數據到Sentinel Dashboard,Sentinel Dashboard將監控和管理應用程序。
2、入門級規則配置詳解(流控規則、降級規則、熱點參數限流)
Sentinel是一款開源的流量控制和降級框架,提供多種限流降級策略,包括流控規則、降級規則、熱點參數限流等。
下面將逐一介紹這些規則。
(1)流控規則
流控規則用于限制系統的流量,可以通過設置QPS流量控制和線程數流量控制等方式來控制系統的訪問速度。
在Sentinel Dashboard中,可以通過以下步驟來配置和管理流控規則:
- 設置流控模式:可以選擇直接拒絕、Warm Up、勻速排隊等模式。
- 設置閾值:可以設置QPS、線程數等閾值來限制流量。
- 設置流控策略:可以選擇按照調用關系、鏈路入口等策略來限制流量。
- 查看已有規則:可以查看已經存在的流控規則,并進行管理和修改。
(2)降級規則
降級規則用于應對系統的異常情況,可以通過設置異常比例降級、異常數降級和慢調用降級等方式來降低系統的負載。
在Sentinel Dashboard中,可以通過以下步驟來配置和管理降級規則:
- 設置降級模式:可以選擇異常比例、異常數和慢調用三種模式。
- 設置閾值:可以設置異常比例、異常數和慢調用時間等閾值來觸發降級。
- 設置降級策略:可以選擇返回特定的錯誤信息、調用備用服務等策略來處理降級情況。
- 查看已有規則:可以查看已經存在的降級規則,并進行管理和修改。
(3)熱點參數限流
熱點參數限流用于對熱點參數進行限流,可以有效避免某些參數被過多地請求。在Sentinel Dashboard中,可以通過以下步驟來配置和管理熱點參數限流規則:
- 設置參數:可以選擇需要進行限流的參數。
- 設置閾值:可以設置QPS、線程數等閾值來限制熱點參數的訪問速度。
- 設置限流策略:可以選擇直接拒絕、勻速排隊等策略來處理熱點參數限流。
- 查看已有規則:可以查看已經存在的熱點參數限流規則,并進行管理和修改。
在使用這些規則時,需要注意參數設置和閾值設置等細節,以避免規則的誤判或限流不準確等問題。
通過Sentinel Dashboard的可視化界面,可以方便地進行規則的配置和管理,提高系統的穩定性和可靠性。
3、資源名與 URL 匹配規則
Sentinel的資源名和URL匹配規則是限流降級策略的重要組成部分,可以根據業務需求定義合適的匹配規則。
- 資源名:可以是一個具體的業務方法、一個接口URL或者一個Dubbo服務等。
- URL 匹配規則:支持Ant匹配和正則匹配兩種方式,可以根據具體需求進行選擇。
- Dubbo服務:Sentinel支持對Dubbo服務進行限流降級操作,需要在Dubbo配置文件中添加Sentinel的攔截器配置。
- 在定義資源名和URL匹配規則時,需要注意合理性和精確性,以避免出現誤判或限流不準確等問題。
上圖展示了應用程序代碼中定義資源名和 URL 匹配規則時的交互過程。
應用程序通過 Sentinel 客戶端向 Sentinel 發送配置請求,Sentinel 返回配置結果。應用程序根據配置結果使用 Sentinel 進行限流降級。
在這個過程中,應用程序需要注意合理性和精確性,以避免出現誤判或限流不準確等問題。
4、自定義 Sentinel 規則擴展開發

上圖是自定義規則擴展的關系圖示。
自定義規則擴展包括數據源擴展、限流降級規則擴展、規則統計擴展等,可以使用多種語言進行開發。
在進行規則擴展時,需要注意代碼質量和性能,以保證擴展的準確性和有效性。
以下是一個自定義規則類型的示例:
public class CustomFlowRule implements FlowRule {
private String resourceName;
private int count;
private int interval;
public CustomFlowRule(String resourceName, int count, int interval) {
this.resourceName = resourceName;
this.count = count;
this.interval = interval;
}
@Override
public String getResource() {
return resourceName;
}
@Override
public int getCount() {
return count;
}
@Override
public void setCount(int count) {
this.count = count;
}
@Override
public int getInterval() {
return interval;
}
@Override
public void setInterval(int interval) {
this.interval = interval;
}
}
在這個示例中,我們自定義了一個 CustomFlowRule 類型,它包含了 resourceName、count 和 interval 三個屬性。同時,我們實現了 FlowRule 接口,并實現了其中的各個方法,以滿足 Sentinel 對規則類型的要求。
使用這個自定義規則類型時,我們需要在代碼中添加相關的配置,例如:
List<CustomFlowRule> rules = new ArrayList<>();
CustomFlowRule rule = new CustomFlowRule("custom_resource", 10, 1);
rules.add(rule);
FlowRuleManager.loadRules(rules);
在這個示例中,我們通過 CustomFlowRule 類型創建了一個規則,它的資源名稱為 custom_resource,限流閾值為 10,時間間隔為 1 秒。然后我們將這個規則添加到 Sentinel 的規則管理器中,從而讓 Sentinel 能夠自動識別和使用這個規則。
四、Spring Cloud Alibaba Sentinel 整合
1、Sentinel Starter 簡介
Sentinel Starter是Spring Cloud Alibaba Sentinel的快速入門依賴,提供了自動化配置和默認規則等能力,可以簡化Sentinel在Spring Cloud中的使用。
在使用Sentinel Starter時,只需要添加依賴并在配置文件中配置相應的參數,即可快速實現Sentinel的限流降級功能。
2、使用 Sentinel Starter 整合 Spring Cloud 微服務
(1)在Spring Boot項目中添加以下依賴:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
(2)在application.yml配置文件中添加以下配置:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制臺地址
port: 8719
datasource:
ds1:
nacos:
server-addr: localhost:8848 # Nacos配置中心地址
dataId: ${spring.application.name}-sentinel # Sentinel配置數據ID
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow,degrade # Sentinel規則類型
(3)在代碼中添加注解 @EnableSentinel ,開啟 Sentinel 功能。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
@EnableSentinel // 開啟 Sentinel 功能
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
(4)使用注解 @SentinelResource 對需要進行限流和降級的接口進行配置。
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/products/{id}")
@SentinelResource(value = "products/{id}", blockHandlerClass = ProductControllerBlockHandler.class, blockHandler = "handleBlock")
public Product getProduct(@PathVariable Long id) {
return productService.getProduct(id);
}
}
其中,@SentinelResource 注解中的 value 參數為資源名稱,blockHandlerClass 和 blockHandler 分別指定了限流或降級時的處理類和方法。
3、限流和降級策略在微服務中的應用場景

在上圖中,我們可以看到當服務請求量過大時,API Gateway 可以對服務進行限流,避免服務過載。同時,當某個服務出現故障或負載過高時,可以對該服務進行降級,避免影響其他服務的正常運行。
4、示例代碼
(1)添加 @SentinelResource 注解
@RestController
public class OrderController {
@PostMapping("/createOrder")
@SentinelResource(value = "createOrder", blockHandlerClass = OrderBlockHandler.class, blockHandler = "handleBlock")
public Result createOrder(@RequestBody OrderRequest orderRequest) {
// ...
}
}
(2)添加 @Idempotent 注解
@RestController
public class OrderController {
@PostMapping("/createOrder")
@SentinelResource(value = "createOrder", blockHandlerClass = OrderBlockHandler.class, blockHandler = "handleBlock")
@Idempotent(key = "#orderRequest.userId + ':' + #orderRequest.productId")
public Result createOrder(@RequestBody OrderRequest orderRequest) {
// ...
}
}
(3)實現冪等性校驗邏輯
@Component
public class OrderService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public boolean checkIdempotency(String key) {
Boolean result = redisTemplate.opsForValue().setIfAbsent(key, "1");
if (result != null && result) {
redisTemplate.expire(key, 60, TimeUnit.SECONDS);
return true;
}
return false;
}
}
五、基于 Sentinel 的分布式鎖實現
1、場景描述
假設我們有一個高并發的秒殺系統,我們需要實現分布式鎖來控制同一時間只能有一個用戶參與秒殺活動。為了防止死鎖和死節點,我們使用 Sentinel 的分布式鎖實現來保證系統的可用性和穩定性。

2、實現步驟
(1)添加 Sentinel 的依賴到項目中:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
(2)在配置文件中添加 Sentinel 的配置:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
port: 8719
(3)在代碼中使用 Sentinel 的分布式鎖實現:
@RestController
public class SeckillController {
@Autowired
private DistributedLock distributedLock;
@GetMapping("/seckill")
public String seckill(@RequestParam("userId") Long userId,
@RequestParam("itemId") Long itemId) {
// 獲取鎖
String lockKey = "seckill:" + itemId;
boolean locked = distributedLock.tryLock(lockKey);
if (!locked) {
return "Failed to get lock";
}
try {
// 執行秒殺邏輯
return "Success";
} finally {
// 釋放鎖
distributedLock.unlock(lockKey);
}
}
}
在 Sentinel 控制臺中創建流控規則,限制流量:
- 在 Dashboard 中創建應用。
- 在 Flow 中創建規則,設置限制流量的策略,例如:QPS 為 1000。
示例代碼:
@Component
public class DistributedLock {
private static final String LOCK_PREFIX = "distributed-lock:";
@Autowired
private CuratorFramework curatorFramework;
public boolean tryLock(String key) {
String lockPath = LOCK_PREFIX + key;
InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);
try {
return lock.acquire(1, TimeUnit.SECONDS);
} catch (Exception ex) {
throw new RuntimeException("Failed to acquire lock", ex);
}
}
public void unlock(String key) {
String lockPath = LOCK_PREFIX + key;
InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);
try {
lock.release();
} catch (Exception ex) {
throw new RuntimeException("Failed to release lock", ex);
}
}
}
六、基于 Sentinel 的 A/B 測試實現
1、場景描述
假設我們有一個電商網站,想要測試一個新的促銷活動頁面對用戶購買行為的影響。我們希望將用戶隨機分為兩個組,其中一個組將看到新的促銷頁面,另一個組將看到舊的促銷頁面。我們希望通過分析兩組用戶的購買轉化率來確定新頁面是否對提高購買轉化率有幫助。
2、實現步驟
- 根據用戶的請求特征將請求分組,例如使用 @SentinelResource 的 blockHandlerClass 和 blockHandler 指定請求被限流或降級時的處理類和方法,處理類中可以根據請求的特征將請求分組。
- 在新的促銷頁面和舊的促銷頁面中分別添加上報代碼,將用戶的購買行為和分組信息上報到 Sentinel。
- 在 Sentinel 控制臺中創建一個流控規則,將兩個組的流量分別限制在一定的范圍內,確保兩組之間的請求量基本相等。
- 分析兩組用戶的購買轉化率,確定新頁面是否對提高購買轉化率有幫助。

3、示例代碼
(1)根據請求特征將請求分組
@RestController
public class PromotionController {
@GetMapping("/promotion")
@SentinelResource(value = "promotion", blockHandlerClass = PromotionBlockHandler.class, blockHandler = "handle")
public String promotion(@RequestParam("userId") Long userId) {
// 根據用戶 id 判斷用戶應該分到哪個組
int groupId = userId % 2;
return "Group " + groupId;
}
}
@Component
public class PromotionBlockHandler {
public String handle(Long userId, BlockException ex) {
// 處理限流或降級情況下的邏輯
int groupId = userId % 2;
return "Blocked Group " + groupId;
}
}
(2)將用戶的購買行為和分組信息上報到 Sentinel
@RestController
public class PromotionController {
@GetMapping("/promotion")
@SentinelResource(value = "promotion", blockHandlerClass = PromotionBlockHandler.class, blockHandler = "handle")
public String promotion(@RequestParam("userId") Long userId, @RequestParam("itemId") Long itemId) {
// 根據用戶 id 判斷用戶應該分到哪個組
int groupId = userId % 2;
// 上報用戶購買行為和分組信息
String resourceName = "promotion_" + itemId;
Entry entry = null;
try {
entry = SphU.entry(resourceName);
Tracer.traceEntry("group_id=" + groupId);
// 執行業務邏輯
return "Success";
} catch (BlockException ex) {
// 處理限流或降級情況下的邏輯
return "Blocked Group " + groupId;
} finally {
if (entry != null) {
entry.exit();
}
}
}
}
(3)在 Sentinel 控制臺中創建流控規則
在 Sentinel 控制臺中創建兩個流控規則,將兩個組的流量分別限制在一定的范圍內,可以通過配置在限流規則中添加特定的參數,如 group_id=0 和 group_id=1,來將不同組的請求進行區分。
示例代碼:
- 在 Sentinel 控制臺中創建流控規則。
- 打開 Sentinel 控制臺,進入流控規則頁面。
- 點擊 “新建” 按鈕,填寫如下信息:
規則名稱:promotion_flow_control;
資源名:promotion_*;
限流閾值:100;
流控模式:QPS;
應用名稱:default;
參數:group_id=0;
點擊 "提交" 按鈕,創建一個限制組 0 的流控規則;
點擊 "新建" 按鈕,填寫如下信息:
規則名稱:promotion_flow_control;
資源名:promotion_*;
限流閾值:100;
流控模式:QPS;
應用名稱:default;
參數:group_id=1;
點擊 “提交” 按鈕,創建一個限制組 1 的流控規則;
注意事項:
在使用 Sentinel 進行 A/B 測試時,需要注意以下幾個方面:
- 將請求進行隨機分組,確保兩個組之間的請求量基本相等。
- 在 Sentinel 控制臺中創建流控規則,限制每個組的流量,確保流量控制的精度和正確性。
- 在上報數據時,需要將用戶的分組信息和購買行為一并上報,以便后續的數據分析。
- 在分析數據時,需要根據不同組的數據進行對比,確保分析結果的準確性。
七、總結
1、Sentinel 的局限和不足
Sentinel雖然具有很多優點和優勢,但也存在一些局限和不足。
例如,Sentinel對業務代碼的侵入性較大,需要在代碼中添加相關的注解或者攔截器等;同時,Sentinel的配置較為復雜,需要進行多種規則的配置和參數的調整等。
此外,Sentinel還存在一些性能問題和安全問題,需要注意規避和解決。
2、Sentinel 的發展前景
盡管Sentinel存在一些不足和局限,但隨著微服務和云原生技術的普及和發展,Sentinel在限流降級等方面的需求和重要性將會越來越大。
同時,Sentinel也在不斷地進行優化和改進,例如在性能和安全方面進行了多項優化和加強,同時還提供了更加方便和高效的規則擴展開發能力,可以滿足不同業務場景的需求。
因此,Sentinel在未來的發展中將會發揮越來越重要的作用,成為云原生技術生態圈中的一顆明珠。
本文轉載自微信公眾號「哪吒編程」,可以通過以下二維碼關注。轉載本文請聯系哪吒編程公眾號。
