熔斷降級規則簡介
熔斷:用來避免微服務架構中雪崩現象,達到某個閾值條件之后自動出發熔斷
原理:當監控到調用鏈路中某一個服務,出現異常(20個以上異常)自動出發熔斷,在出發熔斷之后對於該微服務調用不可用
熔斷降級規則的使用
RT:根據請求響應時間熔斷
異常比例:根據請求調用過程中出現異常百分比進行熔斷
異常數:根據請求調用過程中異常數進行熔斷
平均響應時間
當 1s 內持續進入 N 個請求,對應時刻的平均響應時間(秒級)均超過閾值(count,以 ms 為單位),那么在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的調用都會自動地熔斷(拋出 DegradeException)。注意 Sentinel 默認統計的 RT 上限是 4900 ms,超出此閾值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
異常比例
當資源的每秒請求量 >= N(可配置),並且每秒異常總數占通過量的比值超過閾值(DegradeRule 中的 count)之后,資源進入降級狀態,即在接下的時間窗口(DegradeRule 中的 timeWindow,以 s 為單位)之內,對這個方法的調用都會自動地返回。異常比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%
異常數
當資源近 1 分鍾的異常數目超過閾值之后會進行熔斷。注意由於統計時間窗口是分鍾級別的,若 timeWindow 小於 60s,則結束熔斷狀態后仍可能再進入熔斷狀態。
熱點參數限流規則使用
熱點:經常訪問的數據稱之為熱點
熱點限流:也稱之為熱點參數限流,日后訪問資源中攜帶了指定參數進行限流
@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。 @SentinelResource 注解包含以下屬性:
- value:資源名稱,必需項(不能為空)
- entryType:entry 類型,可選項(默認為 EntryType.OUT)
- blockHandler / blockHandlerClass: blockHandler 對應處理 BlockException 的函數名稱,可選項。blockHandler 函數訪問范圍需要是 public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配並且最后加一個額外的參數,類型為 BlockException。blockHandler 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 blockHandlerClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
- fallback / fallbackClass:fallback 函數名稱,可選項,用於在拋出異常的時候提供 fallback 處理邏輯。fallback 函數可以針對所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進行處理。fallback 函數簽名和位置要求:
- 返回值類型必須與原函數返回值類型一致;
- 方法參數列表需要和原函數一致,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
- fallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 --fallbackClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
- defaultFallback(since 1.6.0):默認的 fallback 函數名稱,可選項,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。默認 fallback 函數可以針對所有類型的異常(除了 exceptionsToIgnore 里面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函數簽名要求:
- 返回值類型必須與原函數返回值類型一致;
- 方法參數列表需要為空,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
- defaultFallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
- exceptionsToIgnore(since 1.6.0):用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣拋出。
注意:使用熱點參數限流時,不能使用資源路徑,必須使用資源別名,sentinel提供資源別名注解 @SentinelResource(value = "別名")
package com.study.springcloudAlibaba.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@RequestMapping("/demo/{id}")
//blockHandler = "" 使用sentinel進行不同規則控制時的默認處理方案
//fallback = "" 自定義業務出錯時默認處理方案
//defaultFallback = "" 指定一個業務錯誤時默認方案
@SentinelResource(value = "aaa",blockHandler = "blockHandler",fallback = "fallCustomer",defaultFallback = "fall") //作用代表這是一個sentinel資源
public String demo(@PathVariable("id") int id){
if (id<0)throw new RuntimeException("id無效");
return "demo ok!!!id="+id;
}
public String blockHandler(int id, BlockException e){
if (e instanceof FlowException){
return "當前請求過於火爆,您已被流量控制!!!";
}
if (e instanceof DegradeException){
return "當前請求過於火爆,您已被降級!!!";
}
if (e instanceof ParamFlowException){
return "當前請求過於火爆,您已被熱點參數限流!!!";
}
return "服務器快爆了,請稍后再試!!!";
}
public String fallCustomer(int id){
return "自定義處理----我們服務器出錯了"+id;
}
public String fall(int id){
return "默認處理----我們服務器出錯了"+id;
}
@RequestMapping("/test")
public String test(){
return "test ok!!!";
}
}
一、
二、
三、
四、
五、