Spring Cloud Feign 使用总结微服务

发布时间:2018-05-17 21:29:10  作者:本站编辑  来源:本站原创  浏览次数:

(1)微服务客户端调用服务提供者提供接口实现方式:

在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate,国内的OKHTTP 其中,用起来最方便、最优雅的还是要属Feign了。Feign是一个声明式的WebService客户端。使用Feign能让编写WebService客户端更加简单,它的使用方法是定义一个接口,然后在接口上添加注解,同时也支持JAX-RS标准的注解。Feign也支持可插拔式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持SpringMVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。从性能上来说OKHTTP 比Feign 好。

(2)Feign实现步骤:

a)l引入jar包:spring-cloud-starter-feign

b)在启动类中添加feign注解@EnableFeignClients:

c)在service方法中添加“@FeignClinet(“service-provider-name”)”注解,如下图所示;

接口中方法的请求方式(GET/POST)跟接口的保持一致。Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中。生成代理时Feign会为每个接口方法创建一个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign的模板化就体现在这里。

注意:

l  @GetMapping注解不支持;

l  @PathVariable注解需要设置value值;

l  @RequestParam注解需要设置value值;

l  接口参数是复杂的JAVA对象的时候,需要采用POST方式请求,且参数名前需要添加@RequestBody注解,且需要保证接口提供者的接口访问方式是POST;

l  客户端的调用接口的FeignClient接口中,方法名、参数名及参数类型必须和接口方法保持一致;参数名前必须添加@PathVariable或者@RequestParam注解。

l  FeignClient注解中没有写其他值,则name值只得是服务提供者的服务名称;如果定义了url,则feignClient会查找对应url上的微服务,name此时的值是指feignClient的名称。name值必须填写,还可以设置其他的值,如configuration(feignClient配置:默认是SpringMvcContract)的值;

l  多个feignCLient类中@FeignClient注解中的name值不能重复,url可以重复;

l  服务提供者的接口参数可以写在请求路径中,也可不写在请求路径中。

d)在Controller方法中引入写好的feignClient接口中的实现方法,即可正常调用远程的接口方法。

(3)指定Feign 调用特定地址 的服务

在功能开发的时候,存在同一个服务多份注册到eureka 的情况,如果希望调用特定的地址服务,那么可以在@FeignClinet(“service-provider-name”)” 中指定url。@FeignClient注解中的service-provider-name属性可以是一个任意字符串,如果与Eureka组合使用,则service-provider-name应为Eureka中的服务名,Feign用它来创建一个Ribbon负载均衡器。也可以通过url属性来指定一个地址,可以是完整的URL,也可以是一个主机名。标注了@FeignClient注解的接口,在ApplicationContext中的Bean实例名是这个接口的全限定名,同时这个Bean还有一个别名,为Bean名+FeignClient。

(4)覆盖Feign的默认配置

SpringCloud对Feign的封装中一个核心的概念就是客户端要有一个名字。每个客户端随时可以向远程服务发起请求,并且每个服务都可以像使用@FeignClient注解一样指定一个名字。SpringCloud会将所有的@FeignClient组合在一起创建一个新的ApplicationContext,并使用FeignClinetsConfiguration对Clients进行配置。配置中包括编码器、解码器和一个feign.Contract。SpringCloud允许你通过configuration属性完全控制Feign的配置信息,这些配置比FeignClientsConfiguration优先级要高:

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>com.netflix.feign</groupId>            

<artifactId>feign-httpclient</artifactId>            

<version>${feign-httpclient}</version>        

</dependency>

然后在application.properties中添加:

feign.httpclient.enabled=true

(5)Feign的Encoder、Decoder和ErrorDecoder

Feign将方法签名中方法参数对象序列化为请求参数放到HTTP请求中的过程,是由编码器(Encoder)完成的。同理,将HTTP响应数据反序列化为java对象是由解码器(Decoder)完成的。

默认情况下,Feign会将标有@RequestParam注解的参数转换成字符串添加到URL中,将没有注解的参数通过Jackson转换成json放到请求体中。注意,如果在@RequetMapping中的method将请求方式指定为POST,那么所有未标注解的参数将会被忽略,例如:

@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET)

void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName, DataObject obj);

  • 2

此时因为声明的是GET请求没有请求体,所以obj参数就会被忽略。

在Spring Cloud环境下,Feign的Encoder*只会用来编码没有添加注解的参数*。如果你自定义了Encoder, 那么只有在编码obj参数时才会调用你的Encoder。对于Decoder, 默认会委托给SpringMVC中的MappingJackson2HttpMessageConverter类进行解码。只有当状态码不在200 ~ 300之间时ErrorDecoder才会被调用。ErrorDecoder的作用是可以根据HTTP响应信息返回一个异常,该异常可以在调用Feign接口的地方被捕获到。我们目前就通过ErrorDecoder来使Feign接口抛出业务异常以供调用者处理。

(6)Feign中Okhttp应用

1、首先在POM中添加如下依赖:

<!-- okhttp -->

<dependency>

<groupId>io.github.openfeign</groupId>

<artifactId>feign-okhttp</artifactId>

</dependency>

2、在application.properties中添加配置:

#feign use okhttp

feign.httpclient.enabled=false

feign.okhttp.enabled=true

3、如下为启动服务请求后的日志记录,红色部分为关注重点:

[2017-06-27 16:44:35.728] [DEBUG] [restartedMain] o.s.c.e.PropertySourcesPropertyResolver -Found key 'feign.okhttp.enabled' in [applicationConfigurationProperties] with type [String]

..........................................................................................................................................................

o.s.c.a.ConfigurationClassBeanDefinitionReader -Registering bean definition for @Bean method org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration$OkHttpFeignLoadBalancedConfiguration.feignClient()

即为在Feign中如何使用Okhttp,非常简单易用,其自动装配源码在FeignRibbonClientAutoConfiguration中阅读


热搜