springcloud中feign的@FeignClient应该写在哪里?

Easter79
• 阅读 611

前言

最近项目组拿了友商的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的控制面板上配置熔断降级策略,形如下

springcloud中feign的@FeignClient应该写在哪里? springcloud中feign的@FeignClient应该写在哪里? springcloud中feign的@FeignClient应该写在哪里? 触发的结果形如下 springcloud中feign的@FeignClient应该写在哪里? 看着已经实现了熔断的效果,但是我这种效果还不是我想要的,于是我又问,如果在面板上进行熔断后,我要记录熔断日志,该怎么做?友商给我的答案是这时候你就得采用分布式链路追踪组件啊比如skywalking,反正你记录日志,不也是为了排查问题方便,要懂得变通。额,好吧,最后我再抛出一个问题,既然你们直接把@FeignClient写在服务提供方的API上,那如果消费端想直连某台服务提供方进行本地联调,那要怎么做?友商的回答是他们开发的时候不会有这种场景,大家都是直连开发环境联调

如果是我来实现,我会把@FeignClient写在哪里?

毋庸置疑的,我会把@FeignClient写在消费端上,因为从职责上,只有消费端才能明确知道自己要调用哪个服务提供方,比如直连哪个服务提供方进行调试,如果直接把@FeignClient写在服务提供方的API上,消费端就很难按需定制。其次因为自己对sentinel也停留在听说过,也没实际用过,也是因为这次友商的项目了用springcloud alibaba的全家桶,才接触了下。后面在和友商讨论@FeignClient的放置问题后,回来在尝试了一把,发现友商说的在sentinel配置熔断降级不全面,因为我后边尝试让服务提供方超时或者报错,此时访问页面就会出现 springcloud中feign的@FeignClient应该写在哪里? springcloud中feign的@FeignClient应该写在哪里? 后边我就按自己的想法,在消费端上会写一个接口继承服务端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

此时让服务提供方超时或者报错,再访问页面 springcloud中feign的@FeignClient应该写在哪里? springcloud中feign的@FeignClient应该写在哪里? 同时控制台打印出熔断日志 springcloud中feign的@FeignClient应该写在哪里?

总结

写这篇文章的目的,并不是要反驳说@FeignClient写在服务提供方API的就是错的,个人是觉得脱离业务场景,来谈技术就是在耍流氓,毕竟友商他们自己那么用,也没出大问题,就说明他们当前的写法是满足他们业务需求。最后我来回答一下,springcloud中feign的@FeignClient应该写在哪里,就我个人而言,我还是倾向写在消费端上,而非服务提供方的API上

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
springboot2结合mybatis拦截器实现主键自动生成
前言前阵子和朋友聊天,他说他们项目有个需求,要实现主键自动生成,不想每次新增的时候,都手动设置主键。于是我就问他,那你们数据库表设置主键自动递增不就得了。他的回答是他们项目目前的id都是采用雪花算法来生成,因此为了项目稳定性,不会切换id的生成方式。朋友问我有没有什么实现思路,他们公司的orm框架是mybatis,我就建议他说,不然让你老大把m
客户希望从云计算供应商那里了解的两件事
云供应商可以通过两个关键的方法改变与客户建立信任并在市场中脱颖而出。虽然许多企业客户喜欢他们的云产品,但他们的供应商经常会抱怨一些普遍的挫败感。不管他们一起做生意多久,组织的规模或他们的云投资的规模,云供应商似乎一遍又一遍地犯同样的错误,最终破坏客户对他们的信任并制造漏洞。通过损害这种宝贵的信任并制造挫折,云供应商通常会不必要地延长销售周期,甚至失去潜在的新
Stella981 Stella981
3年前
Spring Cloud Feign 异常处理
问题最近在项目开发中,使用Feign调用服务,当触发熔断机制时,遇到了以下问题:异常信息形如:TestServiceaddRecord(ParamVO)failedandnofallbackavailable.;获取不到服务提供方抛出的原始异常信息;实现某些业务方法不进入熔断,直接往外抛出异常;
Easter79 Easter79
3年前
Spring工程通过注解实现动态声明Bean
此前在一个旧的spring项目中实现了手动配置接入Eureka,同时生成了一个Feign的客户端。刚好现在有一个新的微服务API需要接入。于是想实现在springboot中通过@FeignClient自动声明客户端bean的功能,过程也不是很复杂,在此分享一下过程一、实现@FeignClient注解@FeignClient是sprin
Wesley13 Wesley13
3年前
Uber的Ringpop和Riak
Uber是最流行的按需用车服务商,他们的创新远不止这些,在生活方式和物流等方面有着快速的进步,最近他们的架构师分享了一些最具有魅力的分布式架构。其中一个不断在进化的分布式系统项目是Ringpop:Ringpop是一个开源的Node.js库,能够在应用级别实现他们的调度平台服务的水平分区sharding。这个额外的抽象层框架,通过众多
Stella981 Stella981
3年前
Spring Cloud微服务架构从入门到会用(三)—服务间调用Feign
微服务最重要的一个功能是服务间调用,各个服务互相依赖。比如电商系统有订单服务,有库存服务。在我们购买一件商品的时候,需要生成订单和减库存。这里我们就要用到服务间调用Feign。Feign是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。接下来我们新建两个modu
Stella981 Stella981
3年前
RabbitMQ实现即时通讯居然如此简单!连后端代码都省得写了?
摘要有时候我们的项目中会用到即时通讯功能,比如电商系统中的客服聊天功能,还有在支付过程中,当用户支付成功后,第三方支付服务会回调我们的回调接口,此时我们需要通知前端支付成功。最近发现RabbitMQ可以很方便的实现即时通讯功能,如果你没有特殊的业务需求,甚至可以不写后端代码,今天给大家讲讲如何使用RabbitMQ来实现即时通讯!MQ
飞速成功案例 | MES系统升级重构,覆盖业务流程各场景功能
1个系统解决所有业务问题覆盖业务流程各场景功能(图片来源于:百度)筑友集团定位为智慧建筑整体解决方案服务商,旨在以EMPC为核心产品,打造涵盖研发、设计、PC构件、装备、施工、新材、装饰、园林、智能家居等业务的全生态链优势企业。筑友集团已在全国22省、45城布局智能化数字工厂,全球首创的EMPC业务模式得到社会和客户广泛认可,目前已服务全国项目600万㎡,工
不是海碗 不是海碗
1年前
运营商三要素验证原理,这篇文章就够了!
引言运营商三要素验证API是一种基于手机号码、身份证号码和姓名等三种信息的验证服务,主要用于验证用户身份信息的真实性和一致性,以及查询手机号码所属的运营商信息。运营商三要素API的验证原理1.身份验证的原理身份信息验证是运营商三要素验证API中的一个重要步
小万哥 小万哥
12个月前
API 参考与帮助内容:一站式开发与使用者支援
API文档API文档是旨在了解API详细信息的综合指南。通常,它们包括端点、请求示例、响应类别和示例以及错误代码等信息。API文档可帮助开发人员了解API端点的具体细节,并了解如何将API成功集成到他们的软件中。文档生成工具API文档生成工具是直接从源代码
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k