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

前言

最近項目組拿了友商的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

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

若是是我來實現,我會把@FeignClient寫在哪裏?

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

在這裏插入圖片描述
後邊我就按本身的想法,在消費端上會寫一個接口繼承服務端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

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

總結

寫這篇文章的目的,並非要反駁說@FeignClient寫在服務提供方API的就是錯的,我的是以爲脫離業務場景,來談技術就是在耍流氓,畢竟友商他們本身那麼用,也沒出大問題,就說明他們當前的寫法是知足他們業務需求。最後我來回答一下,springcloud中feign的@FeignClient應該寫在哪裏,就我我的而言,我仍是傾向寫在消費端上,而非服務提供方的API上code

相關文章
相關標籤/搜索