最近項目組拿了友商的springcloud alibaba項目來進行改造,在翻閱他們的代碼時候,發現他們把@FeignClient寫在服務提供方的API上,他們這樣的寫法成功的引發個人注意,因而抱着好學的心態請教友商的開發人員,因而一篇水文就這麼誕生了java
友商服務提供方的API形以下spring
@FeignClient(name = "feign-provider",path = UserService.INTER_NAME,contextId = "user") public interface UserService { String INTER_NAME = "user"; @GetMapping(value = "/{id}") UserDTO getUserById(@PathVariable("id") Long id); }
我過往的經歷是@FeignClient是寫在消費端上,就是在消費端上會寫一個接口繼承服務端API接口,再打上@FeignClient,並指明fallback,形以下app
@FeignClient(name = "feign-provider",path = UserService.INTER_NAME,contextId = "user",fallback = UserServiceClientFallBack.class) public interface UserServiceClient extends UserService { }
我將我過往的寫法告訴友商開發人員,友商的開發人員對我說,你消費端還要本身寫接口啊,那麼麻煩。咱們這種寫法,消費端僅需pom文件引入API包,在調用方上打個 @Autowired標註,就能夠調用服務提供方的接口。額,他們的說法真的頗有道理,惋惜沒說服我,因而我拋出第二個問題,大家直接把@FeignClient寫在服務提供方的API上,那若是消費端要進行熔斷降級,要怎麼作?分佈式
友商給我答案是用sentinel啊,直接在sentinel的控制面板上配置熔斷降級策略,形以下ide
觸發的結果形以下
看着已經實現了熔斷的效果,可是我這種效果還不是我想要的,因而我又問,若是在面板上進行熔斷後,我要記錄熔斷日誌,該怎麼作?友商給個人答案是這時候你就得采用分佈式鏈路追蹤組件啊好比skywalking,反正你記錄日誌,不也是爲了排查問題方便,要懂得變通。額,好吧,最後我再拋出一個問題,既然大家直接把@FeignClient寫在服務提供方的API上,那若是消費端想直連某臺服務提供方進行本地聯調,那要怎麼作?友商的回答是他們開發的時候不會有這種場景,你們都是直連開發環境聯調ui
毋庸置疑的,我會把@FeignClient寫在消費端上,由於從職責上,只有消費端才能明確知道本身要調用哪一個服務提供方,好比直連哪一個服務提供方進行調試,若是直接把@FeignClient寫在服務提供方的API上,消費端就很難按需定製。其次由於本身對sentinel也停留在據說過,也沒實際用過,也是由於此次友商的項目了用springcloud alibaba的全家桶,才接觸了下。後面在和友商討論@FeignClient的放置問題後,回來在嘗試了一把,發現友商說的在sentinel配置熔斷降級不全面,由於我後邊嘗試讓服務提供方超時或者報錯,此時訪問頁面就會出現
和
後邊我就按本身的想法,在消費端上會寫一個接口繼承服務端API接口,再打上@FeignClient,並指明fallback,形以下spa
@FeignClient(name = "feign-provider",path = UserService.INTER_NAME,contextId = "user",fallback = UserServiceClientFallBack.class) public interface UserServiceClient extends UserService { }
@Component @Slf4j public class UserServiceClientFallBack implements UserServiceClient{ @Override public UserDTO getUserById(Long id) { log.info("id:{} fallback",id); return UserDTO.builder().id(id).userName("fallback").build(); } }
在application.yml激活sentinel對feign的支持調試
feign: sentinel: enabled: true
此時讓服務提供方超時或者報錯,再訪問頁面
同時控制檯打印出熔斷日誌
日誌
寫這篇文章的目的,並非要反駁說@FeignClient寫在服務提供方API的就是錯的,我的是以爲脫離業務場景,來談技術就是在耍流氓,畢竟友商他們本身那麼用,也沒出大問題,就說明他們當前的寫法是知足他們業務需求。最後我來回答一下,springcloud中feign的@FeignClient應該寫在哪裏,就我我的而言,我仍是傾向寫在消費端上,而非服務提供方的API上code