@SentinelResource注解最主要的兩個用法:限流控制和熔斷降級的具體使用。另外,該注解還有一些其他更精細化的配置,如忽略某些異常的配置,默認降級函數等等。
@SentinelResource屬性介紹:
- Value:資源名稱,必需項(不能為空)。
- entryType:entry類型,標記流量的方向,取值IN/OUT,可選項(默認為EntryType.OUT)
- blockHandler:處理BlockException的函數名稱(可以理解對Sentinel的配置進行方法兜底)。函數要求:
- 必須是public修飾
- 返回類型與原方法一致
- 參數類型需要和原方法相匹配,並在最后加BlockException類型的參數。
- 默認需和原方法在同一個類中,若希望使用其他類的函數,可配置blockHandlerClass,並指定blockHandlerClass里面的方法。
- blockHandlerClass:存放blockHandler的類。對應的處理函數必須是public static修飾,否則無法解析,其他要求:同blockerHandler。
- fallback:用於在拋出異常的時候提供fallback處理邏輯(可以理解為對java異常情況方法兜底)。fallback函數可以針對所有類型的異常(除了exceptionsToIgnore里面排除掉的異常類型)進行處理。函數要求:
- 返回類型與原方法一致
- 參數類型需要和原方法相匹配,Sentinel 1.6開始,也可以在方法最后加Throwable類型的參數。
- 默認需和原方法在同一個類中。若希望使用其他類的函數,可配置fallbackClass,並制定fallbackClass里面的方法。
- fallbackClass:存放fallback的類。對應的處理函數必須static修飾,否則無法解析,其他要求:同fallback。
- defaultFallback:用於通用的fallback邏輯。默認fallback函數可以針對所有類型的異常(除了exceptionsToIgnore里面排除掉的異常類型)進行處理。若同時配置了fallback和defaultFallback,以fallback為准。函數要求:
- 返回類型與原方法一致。
- 方法參數列表為空,或者有一個Throwable類型的參數。
- 默認需要和原方法在同一個類中。若希望使用其他類的函數,可配置fallbackClass,並指定fallbackClass里面的方法。
- exceptionsToIgnore:指定排除掉哪些異常。排除的異常不會計入異常統計,也不會進入fallback邏輯,而是原樣拋出。
- exceptionsToTrace:需要trace的異常。
實現限流控制
@RestController public class TestController { @Autowired private TestService testService; @GetMapping("/hello") public String hello() { estService.doSomeThing("hello " + new Date()); return "didispace.com"; } }
啟動測試應用,啟動Sentinel-Dashboard。發一個請求,可以在Sentinel-Dashboard上看到這個請求的相關信息。
實現限流的異常處理
默認情況下,Sentinel對控制資源的限流處理是直接拋出異常。這樣對用戶不友好,需要處理一下。
@Slf4j @Service public class TestService { // 限流與阻塞處理 @SentinelResource(value = "doSomeThing", blockHandler = "exceptionHandler") public void doSomeThing(String str) { log.info(str); } public void exceptionHandler(String str, BlockException ex) { log.error("blockHandler:" + str, ex); } // 熔斷與降級處理 @SentinelResource(value = "doSomeThing2", fallback = "fallbackHandler") public void doSomeThing2(String str) { log.info(str); throw new RuntimeException("發生異常"); } public void fallbackHandler(String str) { log.error("fallbackHandler:" + str); } }
注意:
- 通過@SentinelResource注解的blockHandler屬性制定具體的處理函數。
- 實現處理函數,該函數的傳參必須與資源點的傳參一樣,並且最后加上BlockException異常參數;同時,返回類型也必須一樣。
實現熔斷降級
@SentinelResource注解除了可以用來做限流控制之外,還能實現與Hystrix類似的熔斷降級策略。
@RestController public class TestController { @Autowired private TestService testService; @GetMapping("/hello2") public String hello2() { testService.doSomeThing2("hello2 " + new Date()); return "didispace.com"; } }
@Slf4j @Service public class TestService { // 熔斷與降級處理 @SentinelResource(value = "doSomeThing2", fallback = "fallbackHandler") public void doSomeThing2(String str) { log.info(str); throw new RuntimeException("發生異常"); } public void fallbackHandler(String str) { log.error("fallbackHandler:" + str); } }
啟動測試應用,啟動Sentinel-Dashboard。發一個請求到/hello2接口上,使得Sentinel-Dashboard上可以看到名為doSomeThing2的資源點。然后點擊”降級“按鈕,為該資源設置降級規則。這里使用異常比例策略,比例設置為0.5(即:50%的異常率),時間窗口設置為2(秒)。
驗證熔斷降級,根據上面的降級策略配置,當doSomeThing2方法的調用QPS >= 5,如果異常率超過50%,那么后續2秒內的調用將直接出發熔斷降級,默認情況會直接拋出DegradeException異常。