前言
最近项目组拿了友商的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的控制面板上配置熔断降级策略,形如下
触发的后果形如下
看着曾经实现了熔断的成果,然而我这种成果还不是我想要的,于是我又问,如果在面板上进行熔断后,我要记录熔断日志,该怎么做?友商给我的答案是这时候你就得采纳分布式链路追踪组件啊比方skywalking,反正你记录日志,不也是为了排查问题不便,要懂得变通。额,好吧,最初我再抛出一个问题,既然你们间接把@FeignClient写在服务提供方的API上,那如果生产端想直连某台服务提供方进行本地联调,那要怎么做?友商的答复是他们开发的时候不会有这种场景,大家都是直连开发环境联调
如果是我来实现,我会把@FeignClient写在哪里?
毋庸置疑的,我会把@FeignClient写在生产端上,因为从职责上,只有生产端能力明确晓得本人要调用哪个服务提供方,比方直连哪个服务提供方进行调试,如果间接把@FeignClient写在服务提供方的API上,生产端就很难按需定制。其次因为本人对sentinel也停留在据说过,也没理论用过,也是因为这次友商的我的项目了用springcloud alibaba的全家桶,才接触了下。前面在和友商探讨@FeignClient的搁置问题后,回来在尝试了一把,发现友商说的在sentinel配置熔断降级不全面,因为我后边尝试让服务提供方超时或者报错,此时拜访页面就会呈现
和
后边我就按本人的想法,在生产端上会写一个接口继承服务端API接口,再打上@FeignClient,并指明fallback,形如下
@FeignClient(name = "feign-provider",path = UserService.INTER_NAME,contextId = "user",fallback = UserServiceClientFallBack.class)public interface UserServiceClient extends UserService {}
@Component@Slf4jpublic 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上