Sentinel自定义流控兜底,异常兜底,链路失效,踩坑总结~
想一口吃個(gè)胖子是不可能了,本來想快速過一遍alibaba,做個(gè)項(xiàng)目熟悉一下再深入研究,搞到Sentinel時(shí)遇到一些問題。
首先是流控模式中的鏈路模式時(shí)效問題,無法正確的再控制臺(tái)顯示和流控。已經(jīng)通過https://github.com/alibaba/Sentinel/issues/1213 改好了。親測(cè)可用,我的 sentinel-1.7.1,項(xiàng)目client里用的2.2.0。
下班了,不寫了,明天再寫哈哈哈。
上班了,繼續(xù)!
先說鏈路的問題。
眾所周知懶加載的sentinel dashboard 上面會(huì)展示調(diào)用過的接口信息,然后鏈路綁定時(shí)展示不全,如下
Controller中有兩個(gè)接口,他們同時(shí)調(diào)用了Service的方法
@Autowired
private TestService testService;
@GetMapping("/link1")
public ResponseEntity<String> link1() {
return ResponseEntity.ok(
String.format("link1,調(diào)用test,結(jié)果為%s", testService.hello()));
}
@GetMapping("/link2")
public ResponseEntity<String> lin2() {
return ResponseEntity.ok(
String.format("link2,調(diào)用test,結(jié)果為%s", testService.hello()));
}
又將hello方法注冊(cè)到了sentinel中,這里先不看兜底的方法問題,先解決了這個(gè)鏈路限流失敗的問題。
@Service
public class TestService {
@SentinelResource(value = "hello",
blockHandlerClass = SentinelHandlersClass.class, blockHandler = "handleException",
fallbackClass = SentinelHandlersClass.class,fallback = "handleError")
public String hello() {
return "hello";
}
}
這樣調(diào)用在sentinel中顯示為
很明顯沒有展示全,這就導(dǎo)致了后面一列的問題發(fā)生了,使用鏈路限流會(huì)失效的問題。
解決方法從github上看過了,在這里記錄一下
導(dǎo)包
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-web-servlet</artifactId> </dependency>
至于為什么這么寫還沒有研究,待更....
@Configuration
public class FilterContextConfigSentinel {
/**
* @NOTE 在spring-cloud-alibaba v2.1.1.RELEASE及前,sentinel1.7.0及后,關(guān)閉URL PATH聚合需要通過該方式,spring-cloud-alibaba v2.1.1.RELEASE后,可以通過配置關(guān)閉:spring.cloud.sentinel.web-context-unify=false
* 手動(dòng)注入Sentinel的過濾器,關(guān)閉Sentinel注入CommonFilter實(shí)例,修改配置文件中的 spring.cloud.sentinel.filter.enabled=false
* 入口資源聚合問題:https://github.com/alibaba/Sentinel/issues/1024 或 https://github.com/alibaba/Sentinel/issues/1213
* 入口資源聚合問題解決:https://github.com/alibaba/Sentinel/pull/1111
*/
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
// 入口資源關(guān)閉聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}
我們重啟測(cè)試一下
只要鏈路能正常展示了又搞了一下鏈路限流完全ok了啊。
下面開始說兜底的事。一點(diǎn)一點(diǎn)屢。
先貼一下兜底的代碼
注意
1.兜底方法的參數(shù)要和被的兜底方法的一樣
2.返回值要和被兜底方法的返回值一樣
3.限流兜底方法的 BlockException blockException 必須要有,異常兜底的Throwable blockException參數(shù)好像不是必須,但是沒寫他也沒找到異常兜底。
4.方法必須是public static 修飾。
public class SentinelHandlersClass
{ //限流時(shí)的兜底處理 public static ResponseEntity<String> handleException(BlockException blockException) { return ResponseEntity.ok("兜底了"); } //異常兜底 public static ResponseEntity<String> handleError(Throwable blockException) { return ResponseEntity.ok("兜底了,異常"); } }
@SentinelResource(value = "link1",
blockHandlerClass = SentinelHandlersClass.class, //限流兜底方法所在類
blockHandler = "handleException", //限流時(shí)兜底方法
fallbackClass = SentinelHandlersClass.class, //異常兜底放方法所在類
fallback = "handleError") //異常時(shí)兜底
大概解釋了一下,我們測(cè)試一下,目前是這樣配置的
然后他展示的是這樣,感覺亂七八糟的,
代碼里/link1的@SentinelResource 注解有value屬性,那就是他在sentinel的資源名,而/link2沒有所以給了個(gè)默認(rèn),然后測(cè)試了一下各個(gè)資源名的流控都沒問題。問題是都不走兜底處理,只有l(wèi)ink1走了流控,連/link1的資源都不走,再吐槽一下/link2的資源名默認(rèn)給的那個(gè),完全錯(cuò)誤了,回頭看一下源碼。
以上三個(gè)都不走兜底處理,再展示一下link1。
當(dāng)一秒內(nèi)訪問超過兩次走兜底方法,而不是默認(rèn)的429異常了。
然后再展示一種情況,有關(guān)于這個(gè)兜底的問題文章不是很多,有網(wǎng)友說把@RequestMapping和資源名@SentinelResource的value設(shè)置成一樣的,我們也試一下。
然后我們來做限流,直接給第二個(gè)/link1做。神奇的事情發(fā)生了,/link1接口會(huì)直接返回兜底內(nèi)容,限流以后又返回了默認(rèn)的429錯(cuò)誤。
如圖
這就是親愛的網(wǎng)友給大家留的坑,可能他們?cè)诔┛偷臅r(shí)候也沒動(dòng)什么腦子,給萌新留坑,污染環(huán)境。另外不吐槽原創(chuàng)了,可能版本不一樣,我的版本貼在文章開頭了。
所以找不到兜底方法或者不執(zhí)行兜底方法的問題不在乎接口名和資源名是否相同。改回來以后就沒問題了。需要注意要給資源名做限流,不要給默認(rèn)的做限流,這樣還是會(huì)找不到兜底處理。
異常兜底一樣。
現(xiàn)在再測(cè)試一下下層的hello方法,給他做限流會(huì)返回什么呢。
這里做了兩個(gè)限流,一個(gè)是直接限流hello,另一個(gè)是做了鏈路限流,如圖,當(dāng)hello超過訪問量限制link1的訪問
測(cè)試以后也和普通的一層接口不同,兩個(gè)限流都是直接走異常兜底的。
結(jié)束!再見
總結(jié)
以上是生活随笔為你收集整理的Sentinel自定义流控兜底,异常兜底,链路失效,踩坑总结~的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 包无法安装_R语言基础教程——第2章:R
- 下一篇: [转]Photoshop中的高斯模糊、高