當Spring Cloud Alibaba Sentinel碰上Spring Cloud Sleuth會擦出怎樣的火花

猿天地發表於2020-04-19

前言

今年主要會做一個比較完整的微服務專案開源出來。目前已經開始了,剛興趣的先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。

Sleuth文件:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/single/spring-cloud.html#_spring_cloud_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做了增強。

所以我們只要把兩者結合起來就可以了。

PS:沒Star的現在接著Star吧!

專案:https://github.com/yinjihuan/kitty-cloud

基礎框架:https://github.com/yinjihuan/kitty

相關文章