美文网首页程序员
springcloud中feign的@FeignClient应该

springcloud中feign的@FeignClient应该

作者: linyb极客之路 | 来源:发表于2020-11-28 17:17 被阅读0次

    前言

    最近项目组拿了友商的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上

    相关文章

      网友评论

        本文标题:springcloud中feign的@FeignClient应该

        本文链接:https://www.haomeiwen.com/subject/coxcwktx.html