前言
今年主要會做一個比較完整的微服務專案開源出來。目前已經開始了,剛興趣的先Star一個吧。
專案:https://github.com/yinjihuan/kitty-cloud
基礎框架:https://github.com/yinjihuan/kitty
在做的過程中遇到一個問題那就是標題所說的兩個框架碰撞了火花。都是S開頭的誰都不服誰。
問題描述
既然使用了Sentinel來限流,那麼幹脆熔斷也直接用Sentinel好了,所以就沒使用Hystrix了。
Sentinel對Feign做了適配,使用的時候只需要引入spring-cloud-starter-alibaba-sentinel,如下:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
然後在配置檔案開啟 Sentinel 對 Feign 的支援:feign.sentinel.enabled=true就可以了。
一開始都很正常,平平淡淡的小日子過得也挺舒坦。
突然有一天,來了一位同姓但不同名的哥們,它叫Sleuth。
Spring Cloud Sleuth為Spring Cloud實現了分散式追蹤解決方案。可以配合Zipkin或者Jaeger使用。
自從Sleuth來了之後,Sentinel Feign 的日子就不好過了,莫名其妙熔斷回退失效了。
問題排查
Sentinel 對 Feign 的適配入口在SentinelFeignAutoConfiguration中。
主要是構建了Feign 的 Builder類,只要這個類被自動配置了,那麼Sentinel 對 Feign 的支援也會生效。突然不生效了,那麼肯定是這裡有問題。
於是開啟debug模式,發現啟動的時候這裡沒有執行。feign.sentinel.enabled已經配置了,剩下就只有@ConditionalOnMissingBean的問題了。
@ConditionalOnMissingBean的作用是如果容器中已經有Builder那麼這裡就不會執行。
接下來就要看Sleuth的程式碼了,之所以能馬上知道是Sleuth影響了,是因為一開始都是正常的,加了Sleuth後就出問題了。
在Sleuth中Feign相關的配置是在TraceFeignClientAutoConfiguration中。
可以看到,Sleuth中對Feign Builder也有配置,一種是如果開啟了Hystrix就用SleuthHystrixFeignBuilder,如果沒有開啟就用SleuthFeignBuilder。
在這裡打個斷點,啟動時直接就進來了,這邊執行完後Builder物件就有了,所以Sentinel中的自然就不會執行了。
解決方案
發生衝突的根本原因在於兩個框架都要對Feign進行擴充套件,Sentinel擴充套件是為了再呼叫的時候可以實現限流熔斷等功能。Sleuth擴充套件是為了使用Feign呼叫介面的時候可以傳遞鏈路跟蹤的資訊。
要想解決這個問題,要麼妥協只用一個框架,這樣是最簡單的。
要麼看看Sleuth後面會不會支援Sentinel,目前可以看到已經支援了Hystrix。
最後一種就是自己改原始碼,將Sentinel融入到Sleuth中。
SleuthFeignBuilder 中只是對Client做了包裝。
SentinelFeign 中只是對Builder做了增強。
所以我們只要把兩者結合起來就可以了。