springcloud中feign的@FeignClient應該寫在哪里?


前言

最近項目組拿了友商的springcloud alibaba項目來進行改造,在翻閱他們的代碼時候,發現他們把@FeignClient寫在服務提供方的API上,他們這樣的寫法成功的引起我的注意,於是抱着好學的心態請教友商的開發人員,於是一篇水文就這么誕生了

友商開發人員解惑

友商服務提供方的API形如下

@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,形如下

@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的控制面板上配置熔斷降級策略,形如下

image.png
image.png
在這里插入圖片描述
觸發的結果形如下
image.png
看着已經實現了熔斷的效果,但是我這種效果還不是我想要的,於是我又問,如果在面板上進行熔斷后,我要記錄熔斷日志,該怎么做?友商給我的答案是這時候你就得采用分布式鏈路追蹤組件啊比如skywalking,反正你記錄日志,不也是為了排查問題方便,要懂得變通。額,好吧,最后我再拋出一個問題,既然你們直接把@FeignClient寫在服務提供方的API上,那如果消費端想直連某台服務提供方進行本地聯調,那要怎么做?友商的回答是他們開發的時候不會有這種場景,大家都是直連開發環境聯調

如果是我來實現,我會把@FeignClient寫在哪里?

毋庸置疑的,我會把@FeignClient寫在消費端上,因為從職責上,只有消費端才能明確知道自己要調用哪個服務提供方,比如直連哪個服務提供方進行調試,如果直接把@FeignClient寫在服務提供方的API上,消費端就很難按需定制。其次因為自己對sentinel也停留在聽說過,也沒實際用過,也是因為這次友商的項目了用springcloud alibaba的全家桶,才接觸了下。后面在和友商討論@FeignClient的放置問題后,回來在嘗試了一把,發現友商說的在sentinel配置熔斷降級不全面,因為我后邊嘗試讓服務提供方超時或者報錯,此時訪問頁面就會出現
image.png

在這里插入圖片描述
后邊我就按自己的想法,在消費端上會寫一個接口繼承服務端API接口,再打上@FeignClient,並指明fallback,形如下

@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

此時讓服務提供方超時或者報錯,再訪問頁面
image.png
在這里插入圖片描述
同時控制台打印出熔斷日志
image.png

總結

寫這篇文章的目的,並不是要反駁說@FeignClient寫在服務提供方API的就是錯的,個人是覺得脫離業務場景,來談技術就是在耍流氓,畢竟友商他們自己那么用,也沒出大問題,就說明他們當前的寫法是滿足他們業務需求。最后我來回答一下,springcloud中feign的@FeignClient應該寫在哪里,就我個人而言,我還是傾向寫在消費端上,而非服務提供方的API上


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM