使⽤SpringCloudFeign作为HTTP客户端调⽤远程HTTP服
务的⽅法(推荐)
在Spring Cloud Netflix栈中,各个微服务都是以HTTP接⼝的形式暴露⾃⾝服务的,因此在调⽤远程服务时就必须使⽤HTTP 客户端。我们可以使⽤JDK原⽣的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。但是,⽤起来最⽅便、最优雅的还是要属Feign了。
Feign简介
Feign是⼀种声明式、模板化的HTTP客户端。在Spring Cloud中使⽤Feign, 我们可以做到使⽤HTTP请求远程服务时能与调⽤本地⽅法⼀样的编码体验,开发者完全感知不到这是远程⽅法,更感知不到这是个HTTP请求。⽐如:
@Autowired
private AdvertGropRemoteService service; // 远程服务
public AdvertGroupVO foo(Integer groupId) {
return service.findByGroupId(groupId); // 通过HTTP调⽤远程服务
}
开发者通过service.findByGroupId()就能完成发送HTTP请求和解码HTTP返回结果并封装成对象的过程。
Feign的定义
为了让Feign知道在调⽤⽅法时应该向哪个地址发请求以及请求需要带哪些参数,我们需要定义⼀个接⼝:
@FeignClient(name = "ea") // [A]
public interface AdvertGroupRemoteService {
@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET) // [B]
AdvertGroupVO findByGroupId(@PathVariable("groupId") Integer adGroupId) // [C]
@RequestMapping(value = "/group/{groupId}", method = RequestMethod.PUT)
void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupN
ame)
A: @FeignClient⽤于通知Feign组件对该接⼝进⾏代理(不需要编写接⼝实现),使⽤者可直接通过@Autowired注⼊。
B: @RequestMapping表⽰在调⽤该⽅法时需要向/group/{groupId}发送GET请求。
C: @PathVariable与SpringMVC中对应注解含义相同。
Spring Cloud应⽤在启动时,Feign会扫描标有@FeignClient注解的接⼝,⽣成代理,并注册到Spring容器中。⽣成代理时Feign会为每个接⼝⽅法创建⼀个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求⽅法等信息都是在这个过程中确定的,Feign的模板化就体现在这⾥。
在本例中,我们将Feign与Eureka和Ribbon组合使⽤,@FeignClient(name = "ea")意为通知Feign在调⽤该接⼝⽅法时要向Eureka 中查询名为ea的服务,从⽽得到服务URL。
Feign的Encoder、Decoder和ErrorDecoder
Feign将⽅法签名中⽅法参数对象序列化为请求参数放到HTTP请求中的过程,是由编码器(Encoder)完成的。同理,将HTTP 响应数据反序列化为java对象是由解码器(Decoder)完成的。
默认情况下,Feign会将标有@RequestParam注解的参数转换成字符串添加到URL中,将没有注解的参数通过Jackson转换成json放到请求体中。注意,如果在@RequetMapping中的method将请求⽅式指定为POST,那么所有未标注解的参数将会被忽略,例如:
springmvc面试题 阿里@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET)
void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName, DataObject obj);
此时因为声明的是GET请求没有请求体,所以obj参数就会被忽略。
在Spring Cloud环境下,Feign的Encoder*只会⽤来编码没有添加注解的参数*。如果你⾃定义了Encoder, 那么只有在编码obj 参数时才会调⽤你的Encoder。对于Decoder, 默认会委托给SpringMVC中的MappingJackson2HttpMessageConverter类进⾏解码。只有当状态码不在200 ~ 300之间时ErrorDecoder才会被调⽤。ErrorDecoder的作⽤是可以根据HTTP响应信息返回⼀个异常,该异常可以在调⽤Feign接⼝的地⽅被捕获到。我们⽬前就通过ErrorDecoder来使Feign接⼝抛出业务异常以供调⽤者处理。
Feign的HTTP Client
Feign在默认情况下使⽤的是JDK原⽣的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持⼀个长连接,
即利⽤HTTP的persistence connection 。我们可以⽤Apache的HTTP Client替换Feign原始的http client, 从⽽获取连接池、超时时间等与性能息息相关的控制能⼒。Spring Cloud从Brixtion.SR5版本开始⽀持这种替换,⾸先在项⽬中声明Apache HTTP Client和feign-httpclient依赖:
<!-- 使⽤Apache HttpClient替换Feign原⽣httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>comflix.feign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>${feign-httpclient}</version>
</dependency>
然后在application.properties中添加:
abled=true
总结
通过Feign,我们能把HTTP远程调⽤对开发者完全透明,得到与调⽤本地⽅法⼀致的编码体验。这⼀点与阿⾥Dubbo中暴露远程服务的⽅式类似,区别在于Dubbo是基于私有⼆进制协议,⽽Feign本质上还是个HTTP客户端。如果是在⽤Spring Cloud Netflix搭建微服务,那么Feign⽆疑是最佳选择。
以上所述是⼩编给⼤家介绍的使⽤Spring Cloud Feign作为HTTP客户端调⽤远程HTTP服务的⽅法(推荐),希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。在此也⾮常感谢⼤家对⽹站的⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论