本文共 6310 字,大约阅读时间需要 21 分钟。
通过之前的几篇博文,我简单介绍了OpenFeign的使用及其工作原理。OpenFeign的易用性和扩展性让人印象深刻。接下来,我将继续学习Spring是如何对OpenFeign进行集成支持,使其在Spring Cloud 微服务体系中发挥着重要的作用。在本篇博文中,我将结合官方文档介绍Spring Cloud OpenFeign,了解其基本使用方式及功能特性。
进行服务间的调用无外乎HTTP请求或者RPC调用,在Spring Cloud 微服务体系中也支持了这两种方式。分别是以HTTP请求为基础的Spring Cloud OpenFeign 和阿里的dubbo。Spring Cloud OpenFeign 则是以OpenFign为基础,通过自动装配将其集成到Spring Boot应用中,纳入到Spring体系中。
通过官方文档我们可以初步了解Spring Cloud对OpenFeign做了那些改造支持。
Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.
可以看到Spring Cloud添加了对Spring MVC注解的支持和Spring Web使用的HttpMessageConverters, 并且集成了Ribbon 和 Eureka,提供了可以进行负载均衡了Http Client。
接下来,通过简单项目介绍如何使用Spring Cloud OpenFeign。
首先引入Spring Cloud OpenFeign 依赖,同时因为基于Eureka的服务注册发现,还要引入Eureka-Client 依赖。基于Spring Boot 2.1.14版本:
org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-openfeign
引入后,在项目启动类分别加上@EnableDiscoveryClient和@EnableFeignClients注解:
@EnableDiscoveryClient@EnableFeignClients@SpringBootApplicationpublic class Feign2ClientApplication { public static void main(String[] args) { SpringApplication.run(Feign2ClientApplication.class, args); }}
在application.yml中配置项目名称,端口和注册中心Eureka地址:
spring: application: name: feign2-clientserver: port: 2003eureka: client: service-url: defaultZone: http://localhost:1001/eureka/
创建服务接口,使用@FeignClient注解:
@FeignClient(value = "feign2")public interface Feign2Service { }
至此,OpenFeign的服务已经配置完毕,通过@Autowired自动注入进行服务调用。
@Autowiredprivate Feign2Service feign2Service;
可以看到与之前OpenFeign的使用方式相比,我们不再需要使用其他注解配置,不用进行手动创建Feign Client 直接使用SpringMVC的注解, @FeignClient注解即可。同时,Spring Cloud OpenFeign 也支持了手动创建Feign Client,这种方式与OpenFeign相似,这里不再赘述,更多请看官方文档。
在@FeignClient注解的value值表示client名称,该名称被用来创建Ribbon load-balancer或者 Spring Cloud LoadBalancer 。负载均衡器通过该名称进行服务端物理地址的获取,如果项目是eureka-client,则通过eureka注册中心进行服务地址解析。
同时,如果项目没有使用eureka注册中心,@FeignClient注解也支持通过配置url参数来指定服务端的url。同时,文档提到也可以使用SimpleDiscoveryClient,并配置服务地址列表。
If you don’t want to use Eureka, you can simply configure a list of servers in your external configuration using SimpleDiscoveryClient.
没有eureka注册中心,通过url指定服务地址:
@FeignClient(value = "feign2", url = "http://localhost:2003")public interface Feign2Service {}
文档提到,为了保持向后兼容性,Rabbion作为默认的负载均衡器实现。但是由于Spring Cloud Netfix Ribbon项目已经进入维护状态,官方建议使用Spring Cloud LoadBalancer进行替代。可以设置spring.cloud.loadbalancer.ribbon.enabled 值为false进行配置。
先通过文件上传示例代码来了解如何修改Spring Cloud OpenFeign的默认配置:
在OpenFeign的feign-form项目中,我们了解了如何实现表单提交,主要是配置Encoder。在Spring中,我们需要配置SpringFormEncoder。
这里不需要引入额外的依赖,在spring-cloud-starter-openfeign依赖中,已经引入了feign-java8依赖,该依赖包含了feign-form和feign-form-spring。
@FeignClient(value = "feign2", configuration = Feign2Service.MultipartSupportConfig.class)public interface Feign2Service { @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) String handleFileUpload(@RequestPart(value = "file") MultipartFile file); @Configuration class MultipartSupportConfig{ @Bean public SpringFormEncoder feignFormEncoder(){ return new SpringFormEncoder(); } }}
可以看到,先配置生成了SpringFormEncoder的bean对象,然后在@FeignClient注解中配置configuration值来修改默认Encoder。
这里使用的并不是spring标准的encoder配置,标准配置请看文档 或者这篇博文。通过文档我们可以了解到,Spring Cloud Netflix为feign提供了一些默认配置:
注意,spring-cloud-starter-openfeign依赖已经同时引入了spring-cloud-starter-netflix-ribbon 和 spring-cloud-starter-loadbalancer。
对于OpenFeign的默认Client : OkHttpClient和ApacheHttpClient,可以通过设置feign.okhttp.enabled 或 feign.httpclient.enabled 值为true进行启用。同时也可以自定义HttpClient。
在之前OpenFeign的使用介绍中,我们了解到OpenFeign有默认的重试器Retryer和对QueryMap的支持。但是Spring Cloud OpenFeign并没有对以下配置进行默认实现:
通过以上文件传输方法配置可知,Spring Cloud OpenFeign提供了在@FeignClient注解中设置configuration值来覆盖默认配置的方法。对此我们可以通过该方式来配置以上自实现的Retryer, Interceptor, Logger.Level等。
@Configurationclass Config{ @Bean public Retryer retryer() { return new MyRetryer(); } @Bean public RequestInterceptor interceptor() { return new RequestHeaderInterceptor(); } @Bean public Logger.Level level() { return Logger.Level.FULL; }}
@FeignClient(value = "feign2", configuration = Feign2Service.Config.class)public interface Feign2Service { }
同时,我们也可以通过配置文件的方式对Feign进行配置,在application.yml中进行一下配置:
feign: client: config: feign2: connectTimeout: 5000 readTimeout: 5000 loggerLevel: full encoder: feign.form.spring.SpringFormEncoder requestInterceptors: - com.example.feign2.interceptor.RequestHeaderInterceptor
注意,config下级为对应feign的名称。
对于所有Feign的默认配置,可以像以上展示的那样通过在@EnableFeignClients注解中设置defaultConfiguration值进行配置,又或者通过配置文件,将config下级对应feign的名称设置为default。
如果同时在注解中设置了Configuration 对象 和在配置文件中进行了配置,此时配置文件的属性值会覆盖注解中的配置。如果想改变此优先级,可以设置feign.client.default-to-properties值为false。
对于OpenFeign日志的支持,在只有log level为debug时,才会输出日志。因此需要在配置文件中设置对应类的日志等级:
logging: level: com: example: feign2: service: debug
关于日志等级的分类,在之前的博文中我已经介绍过,在此不再赘述。
关于更多了Spring Cloud OpenFeign的默认配置值,请看文档。
在之前OpenFeign介绍中,我们已经知道OpenFeign使用@QueryMap注解将POJO转换为GET请求参数。但是Spring Clound OpenFeign 并不支持该注解,因为它缺少Value属性。
为此,Spring Cloud OpenFeign提供了一个等效的注解@SpringQueryMap,该注解可以将一个POJO或者是Map参数转换为请求参数。
public class User { private String uname; private String pwd; ...getter setter}
@FeignClient(value = "feign2")public interface Feign2Service { @GetMapping("/hi") String hi(@SpringQueryMap User user);}
与@QueryMap注解一样,会将POJO的参数名称或者Map的key值作为请求的参数名称。若需要改动,则可以自实现QueryMapEncoder bean。
至此,对Spring Cloud OpenFeign的简单使用及配置已经介绍完毕,接下来我将继续对Sprig Cloud OpenFeign 其他功能特性进行学习总结。
参考资料:
https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.2.3.RELEASE/reference/html/#feign-querymap-support转载地址:http://gdeii.baihongyu.com/