Sentinel 筆記
1 介紹
Sentinel 是阿里開源的分布式系統流量防衛組件,專注于 流量控制、熔斷降級、系統保護。
官網:https://sentinelguard.io/zh-cn/index.html
wiki:https://github.com/alibaba/Sentinel/wiki
對比同類產品:
產品 | 特點 |
---|---|
Hystrix | Netflix 開源,功能全面但已停止維護,基于線程池隔離,資源消耗較大 |
Resilience4j | 輕量級,基于函數式編程,但需要結合其他組件實現完整功能 |
Sentinel | 輕量級,實時監控和控制,支持動態規則配置,與 Spring Cloud 深度集成 |
2 架構
- 核心模塊:
- 資源:被保護的代碼邏輯(如接口、方法)。
- 規則:流量控制、熔斷降級等策略。
- 控制臺:可視化規則配置與實時監控。
4 環境搭建
4.1 依賴
<!-- Spring Cloud Alibaba Sentinel -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
4.2 啟動控制臺
-
下載 Sentinel Dashboard 官方 Release或📎sentinel-dashboard-1.8.8.jar
-
啟動命令:
下載完成后:在文件目錄輸入cmd進入bash命令行
在命令行窗口輸入:即可啟動項目
java -jar sentinel-dashboard-1.8.8.jar
3.通過http://localhost:8080即可訪問sentinel的控制臺
正常訪問后顯示的界面:
4.3 配置連接
在 application.yml
中配置:
# 訂單以及商品都要配置
spring:cloud:sentinel:transport:dashboard: localhost:8080 # 控制臺地址eager: true # 立即初始化
配置成功后:
假設我們要把createOrder注冊為我們要管理的服務。
@SentinelResource(value = "createOrder")public Order createOrder(Long userId, Long productId) {//Product product = productFeignClient.getProductById(productId);//使用RestTemplate實現負載均衡//Product product = getProductFromRemqteWithLoadBalanceAnnotation(productId);//使用feignClient實現遠程調用Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1L);order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));//order.setTotalAmount(BigDecimal.valueOf(0));order.setUserId(userId);order.setNickName("zhangsan");order.setAddress("尚硅谷");order.setProductList(Arrays.asList(product));return order;}
創建訂單的請求:http://localhost:8000/order/create?userId=1&productId=100
接下來就可以對資源進行流控。
QPS:每秒能接收的請求數
5 異常處理
5.1 自定義 BlockExceptionHandler
目的:處理業務異常,出現異常可以給前端傳遞一些消息。
實現 BlockExceptionHandler
接口,處理流控/熔斷異常:
// order模塊下
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {private ObjectMapper objectMapper = new ObjectMapper();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response,String resourceName, BlockException e) throws Exception {response.setStatus(429); //too many requestsresponse.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();R error = R.error(500, resourceName + " 被Sentinel限制了,原因:" + e.getClass());String json = objectMapper.writeValueAsString(error);writer.write(json);writer.flush();writer.close();}
}
5.2 blockHandler
使用 @SentinelResource
注解指定降級方法:
@SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")@Overridepublic Order createOrder(Long productId, Long userId) {
// Product product = getProductFromRemoteWithLoadBalanceAnnotation(productId);//使用Feign完成遠程調用Product product = productFeignClient.getProductById(productId);Order order = new Order();order.setId(1L);// 總金額order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("zhangsan");order.setAddress("尚硅谷");//遠程查詢商品列表order.setProductList(Arrays.asList(product));return order;}//出現異常,兜底回調public Order createOrderFallback(Long productId, Long userId, BlockException e){Order order = new Order();order.setId(0L);order.setTotalAmount(new BigDecimal("0"));order.setUserId(userId);order.setNickName("未知用戶");order.setAddress("異常信息:"+e.getClass());return order;}
//沒自定義異常,就會自動向上拋,最后給Spring的全局攔截器捕獲到,由spring去處理異常
5.3 OpenFeign-兜底回調
- 實現 Fallback 類:
@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class) // feign客戶端
public interface ProductFeignClient {//mvc注解的兩套使用邏輯//1、標注在Controller上,是接受這樣的請求//2、標注在FeignClient上,是發送這樣的請求@GetMapping("/product/{id}")Product getProductById(@PathVariable("id") Long id);}
2.在 Feign 接口中指定:
@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserService { /* ... */ }
6 規則 - 流量控制
6.1 閾值類型
- QPS:每秒請求數。
- 線程數:并發線程數。
6.2 流控模式
- 直接:針對當前資源。
- 關聯:關聯資源觸發閾值時限流。
- 鏈路:基于調用鏈路限流。
6.3 流控效果
- 快速失敗:直接拒絕請求。
- Warm Up:預熱模式,逐步增加閾值。
- 排隊等待:請求進入隊列等待處理。
7 規則 - 熔斷降級
7.1 斷路器狀態
- Closed:正常狀態。
- Open:熔斷狀態,拒絕所有請求。
- Half-Open:嘗試放行部分請求探測恢復情況。
7.2 工作原理
- 慢調用比例:響應時間超過閾值且比例超限。
- 異常比例:異常比例超限。
- 異常數:異常數超限。
7.3 熔斷與兜底
8 規則 - 熱點參數
8.1 環境搭建
- 添加熱點參數限流規則:
@GetMapping("/seckill")@SentinelResource(value = "seckill-order",fallback = "seckillFallback")public Order seckill(@RequestParam(value = "userId",required = false) Long userId,@RequestParam(value = "productId",defaultValue = "1000") Long productId){Order order = orderService.createOrder(productId, userId);order.setId(Long.MAX_VALUE);return order;}public Order seckillFallback(Long userId,Long productId, BlockException exception){System.out.println("seckillFallback....");Order order = new Order();order.setId(productId);order.setUserId(userId);order.setAddress("異常信息:"+exception.getClass());return order;}
重點總結
- 核心功能:
- 流量控制(QPS/線程數)、熔斷降級(慢調用/異常比例)、熱點參數限流。
- 優勢:
- 動態規則配置,實時監控,與 Spring Cloud 無縫集成。
- 實操關鍵:
- 控制臺啟動后需配置
spring.cloud.sentinel.transport.dashboard
。 - 使用
@SentinelResource
定義資源和降級邏輯。 - OpenFeign 需結合 Fallback 類實現服務降級。
- 控制臺啟動后需配置
- 注意事項:
- 規則配置后需持久化到 Nacos/Redis,避免重啟丟失。
- 生產環境建議開啟 Sentinel 的集群流控功能。