小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
本章节还是围绕以前的章节来做一个展开,前情回顾,有个需求是要对外开放接口,在微服务中对外开放接口不可能让用户直接访问对应服务的,这样会减少服务器的安全性。所以我们公司的架构采用构建第三方OpenApi服务来给外部访问,认证方式也是走的Oauth2的客户端模式。
有了OpenApi服务后,客户不会直接对我们的服务进行一个访问,所有的第三方接口请求都经过OpenApi来进行转发访问,注意这里的转发和网关的转发概念不一样。网关转发是直接把请求打进来,而OpenApi服务的转发是指服务本身使用各种获取数据的手段来拿到客户想要的数据,当然这些数据都是我们服务允许的范围内。
这个手段也就是我们今天要聊的Feign 远程调用,它是网飞公司推出的微服务生态解决方案的五大神兽之一。网飞也就是大家熟知的那个视频网站,Netflix(Nasdaq NFLX) 美国奈飞公司,简称网飞。是一家会员定制的流媒体平台。这么大个视频网站背后肯定是多个服务组合起来的应用,不然如何扛起并发的问题。
Feign 的前身Ribbon
feign更像是ribbon的扩展版本,ribbon专注于负载均衡,而feign专注于远程调用。
ribbon也是可以实现远程调用的,当然底层用的都是那一套也就是RestTemplate来实现,只不过ribbon是使用原生调用,而feign是在此基础上进行了封装,并且加入了fallback机制,成功返回数,失败返回对应fallback信息。feign是一个使用起来更加方便的Http客户端。这些操作使得feign用起来仿佛并不是在远程调用,而是在调用本地方法一样。
Feign 的基本使用
首先导入openfeign这个包,后续代码需要这个包的支持
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
feign的使用非常简单,看以下代码你基本就学会使用了。
这里主要讲一下下面的各个字段
- @Component feign需要注入到bean容器中
- @FeignClient feign客户端的注解,name为需要调用的服务名,contextId是为了防止作用域重复所以必须要设定一个不重复的id,与bean name的情况类似,一个容器不能有两个同样命名的bean。fallbackFactory失败回调的方法内容
- @RequestMapping 远程调用接口地址,value调用接口地址,method 调用方法属于什么Http请求,consumes取决于你调用的生产者属于什么类型,一般默认application/json,也有可能生产者更换了类型,这时候需要找你的生产者核对一下。
/*
* @author MouthMouth
* @since 2021/10/6
*/
@Api("远程服务接口")
@Component
@FeignClient(
name = "wf-platform-equipment",
contextId = "AeratorFeign",
fallbackFactory = AeratorFallback.class
)
public interface AeratorFeign {
@RequestMapping(
value = "/v1/{tenantId}/aerator",
method = RequestMethod.POST,
consumes = "application/json")
ResponseEntity<String> add(@PathVariable(value = "tenantId") Long tenantId,
@RequestBody Aerator aerator);
}
下面代码为上方fallback的内容,方法调用出现异常就会进入下面代码进行一个异常处理。
@Component
@Slf4j
public class AeratorFallback implements FallbackFactory<AeratorFeign> {
@Override
public AeratorFeign create(Throwable throwable) {
return null;
}
}
总结
- feign是ribbon的扩展版,主要扩展了远程调用方面
- 远程调用主要通过RestTemplate
- feign的目标是让使用者调用远程方法更像是在调用本地方法一样