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