- 1.OpenFeign介绍
- 2 .快速开始
- 3 OpenFeign自定义配置
- 3.1 日志配置
- 3.2 契约(Contract)配置
- 3.3 超时时间配置
- 3.4 Feign 默认 Http Client 修改
- 3.5 创建多个具有相同名称或 url 的 feign 客户端
- 3.6 自定义拦截器实现认证逻辑
- 3.7 Feign负载均衡
- 4 Feign的配置属性
在使用 Spring Cloud 开发微服务应用时,各个服务提供者都是以 HTTP 接口的形式对外提供服务,因此在服务消费者调用服务提供者时,底层通过 HTTP Client 的方式访问。此时可以使用 JDK 原生的 URLConnection、Apache 的 HTTP Client、Netty 的异步 HTTP Client 或者 Spring 的 RestTemplate 去实现服务间的调用。但是最方便、最优雅的方式是通过 Feign 进行服务间的调用。Feign 是由 Netflix 开发的一个声明式的 Web Service 客户端,它的出现使开发 Web Service 客户端变得很简单;Feign 同时也是一款声明式、模板化的 HTTP 客户端
Spring Cloud OpenFeign 对 Feign 进行了二次封装,使得在 Spring Cloud 中使用 Feign 的时候,可以做到使用 HTTP 请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程访问,更感知不到在访问 HTTP 请求。Spring Cloud OpenFeign 增强了 Feign 的功能,使 Feign 有限支持 Spring MVC 的注解,如 @RequestMapping 等。OpenFeign 的 @FeignClient 注解可以解析 Spring MVC 的 @RequestMapping 注解下的接口
2 .快速开始本 文 实 例 使 用 的 S p r i n g C l o u d 版 本 是 : 2020.0.4 , S p r i n g B o o t 版 本 是 : 2.5.6 本文实例使用的Spring Cloud版本是:2020.0.4,Spring Boot版本是:2.5.6 本文实例使用的SpringCloud版本是:2020.0.4,SpringBoot版本是:2.5.6
-
引入依赖
org.springframework.cloud spring-cloud-starter-openfeign -
编写调用接口,并使用@FeignClient注解
@FeignClient(name = "order-service-resume",path ="/order") public interface ResumeServuceFeignClient { @RequestMapping("/findResumeByUserId/{userId}") Resume findResumeByUserId(@PathVariable Long userId); @RequestMapping("/getPort") Integer getPort(); }- name: 指定调用rest接口所对应的服务名称
- path:指定调用rest接口Controller的@RequestMapping("/order")
- name: 指定调用rest接口所对应的服务名称
-
在启动类添加@EnableFeignClients 注解
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @LoadBalancerClients(defaultConfiguration = {LoadBalancerConfiguration.class}) public class AutodeliverApplication8091 { public static void main(String[] args) { SpringApplication.run(AutodeliverApplication8091.class,args); } } -
发起调用,像调用本地方法一样调用远程服务
@Slf4j @RestController @RequestMapping("/test") public class AutoDeliverController { @Autowired ResumeServuceFeignClient feignClient; @GetMapping("/testLoadBalanced") public Integer getPort(){ return feignClient.getPort(); } }
-
定义一个配置类,指定日志级别
public class FeignConfig { @Bean public Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }OpenFeign的日志级别有4种,分别是:
-
NONE:不记录任何日志(默认值)。适合生产环境。
-
BASIC:仅记录请求⽅法、URL、响应状态码以及执⾏时间。适合⽣产问题追踪
-
HEADERS:在BASIC级别的基础上,记录请求和响应的header。
-
FULL:记录请求和响应的header、body和元数据。适⽤于开发及测试环境定位问题
-
-
局部配置,让调用的微服务生效,在@FeignClient注解中指定配置类
@FeignClient(name = "order-service",path ="/order",configuration = FeignConfig.class) public interface ResumeServuceFeignClient { @RequestMapping("/findResumeByUserId/{userId}") Resume findResumeByUserId(@PathVariable Long userId); @RequestMapping("/getPort") Integer getPort(); }如果在FeignConfig加上@Configuration注解,则此配置全局生效,如果想要指定的微服务生效,则不能添加@Configuration注解。
-
在配置文件中配置
可以通过指定feignName,实现局部配置,只让某个客户端生效。比如,只让order-service 微服务生效:
feign: client: config: order-service: loggerLevel: full如果想要全局配置,可以指定default,,下面的配置是全局生效。
feign: client: config: default: loggerLevel: full
如果通过 Java 代码的方式配置过 Feign,然后又通过 application.yml 或者 application.properties 属性文件的方式配置 Feign,默认情况下属性文件中 Feign 的配置会覆盖 Java 代码的配置。但是可以通过使用参数 feign.client.default-to-properties=false 来改变 Feign 配置生效的优先级。
3.2 契约(Contract)配置Spring Cloud在Feign的基础上做了扩展,使用SpringMVC的注解完成Feign的功能。原生的Feign是不支持SpringMVC注解的,如果你想在Spring Cloud中使用原生的注解方式来定义客户浩也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。
Spring Cloud早期版本就是用的原生Feign,随着netflix的停更替换成了openfeign
-
修改契约配置,支持原生Feign的注解
public class FeignConfig { @Bean public Contract feignContract() { return new feign.Contract.Default(); } }修改契约配置后,@FeignClient不在支持SpringMVC注解,需要使用Feign原生的注解。
我们可以在默认客户端和命名客户端上配置超时。 OpenFeign 使用两个超时参数:
- connectTimeout 连接超时时间,默认2s
- readTimeout 请求处理超时时间,默认5s
以下是在默认客户端配置,全局生效:
feign:
client:
config:
default:
connectTimeout: 5000 #连接超时时间,默认2s
readTimeout: 2000 # 请求处理超时时间,默认5s
loggerLevel: basic
在Java类中配置超时时间:
@Bean
public Request.Options options(){
return new Request.Options(5000,10000);
}
3.4 Feign 默认 Http Client 修改
Feign 在默认情况下使用的是 JDK 原生的 URLConnection 发送 HTTP 请求,没有使用连接池。
Feign支持以下Http请求客户端:
- OkHttpClient :通过 feign.okhttp.enabled=true 配置开启
- ApacheHttpClient: 通过 feign.httpclient.enabled=true配置开启
- ApacheHC5 :通过feign.httpclient.hc5.enabled=true 配置开启
使用 Apache HTTP Client 替换 Feign 默认的 Client
替换步骤非常简单,只需要在 pom.xml 与 application.yml 分别添加以下配置内容即可:
- 添加依赖:
io.github.openfeign feign-httpclient
-
添加配置
feign: httpclient: enabled: true
如果我们想创建多个具有相同名称或 url 的 feign 客户端,以便它们指向同一服务器但每个具有不同的自定义配置,那么我们必须使用 @FeignClient 的 contextId 属性以避免这些配置的名称冲突Bean。
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {
//..
}
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {
//..
}
也可以将 FeignClient 配置为不从父上下文继承 bean。您可以通过覆盖 FeignClientConfigurer bean 中的 inheritParentConfiguration() 以返回 false 来实现此目的:
@Configuration
public class CustomConfiguration{
@Bean
public FeignClientConfigurer feignClientConfigurer() {
return new FeignClientConfigurer() {
@Override
public boolean inheritParentConfiguration() {
return false;
}
};
}
}
3.6 自定义拦截器实现认证逻辑
-
实现RequestInterceptor 接口
public class FeignAuthRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { //模拟token String access_token= UUID.randomUUID().toString(); //在head中添加authorization参数 requestTemplate.header("authorization",access_token); } } -
在配置类中加入自定义的拦截器
public class FeignConfig { public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){ return new FeignAuthRequestInterceptor(); } }
@FeignClient(name = "order-service-resume",path ="/order",configuration = FeignConfig.class)
public interface ResumeServuceFeignClient {
@RequestMapping("/getPort")
Integer getPort();
}
3.7 Feign负载均衡
spring-cloud-starter-openfeign 支持 spring-cloud-starter-loadbalancer。但是,作为一个可选的依赖项,如果您想使用它,您需要确保将其添加到您的项目中。
org.springframework.cloud spring-cloud-starter-loadbalancer
如果项目中,使用了Eureka作为注册中心,spring-cloud-starter-netflix-eureka-client,中包含了spring-cloud-starter-loadbalancer的依赖,如果已经引入了eureka组件,则无需单独引入spring-cloud-starter-loadbalancer 。
默认的负载均衡算法为RoundRobinLoadBalancer (轮询)
关于loadbalancer的使用方法,可以参考我的另外一篇博文:https://blog.csdn.net/warybee/article/details/121284159?spm=1001.2014.3001.5501
4 Feign的配置属性可以在 application.properties 文件、application.yml 文件或命令行开关中指定各种属性。本附录提供了常见 Spring Cloud OpenFeign 属性的列表以及对使用它们的底层类的引用。
| 名称 | 默认值 | 描述 |
|---|---|---|
| feign.autoconfiguration.jackson.enabled | false | 如果为 true,将为 Jackson 页面解码提供 PageJacksonModule 和 SortJacksonModule bean。 |
| feign.circuitbreaker.enabled | false | 如果为 true,则 OpenFeign 客户端将使用 Spring Cloud CircuitBreaker 断路器包装。 |
| feign.circuitbreaker.group.enabled | false | 如果为 true,则 OpenFeign 客户端将使用带有组的 Spring Cloud CircuitBreaker 断路器包装。 |
| feign.client.config | ||
| feign.client.decode-slash | true | Feign 客户端默认不编码斜杠/字符。要更改此行为,请将 decodeSlash 设置为 false。 |
| feign.client.default-config | default | |
| feign.client.default-to-properties | true | |
| feign.client.refresh-enabled | false | 为 Feign 启用选项值刷新功能。 |
| feign.compression.request.enabled | false | 使 Feign 发送的请求能够被压缩。 |
| feign.compression.request.mime-types | [text/xml, application/xml, application/json] | 支持的 MIME 类型列表。 |
| feign.compression.request.min-request-size | 2048 | 最小阈值内容大小。 |
| feign.compression.response.enabled | false | 使来自 Feign 的响应能够被压缩。 |
| feign.compression.response.useGzipDecoder | false | 启用要使用的默认 gzip 解码器。 |
| feign.encoder.charset-from-content-type | false | 指示字符集是否应从 {@code Content-Type} 标头派生。 |
| feign.httpclient.connection-timeout | 2000 | |
| feign.httpclient.connection-timer-repeat | 3000 | |
| feign.httpclient.disable-ssl-validation | false | |
| feign.httpclient.enabled | true | 允许 Feign 使用 Apache HTTP 客户端。 |
| feign.httpclient.follow-redirects | true | |
| feign.httpclient.hc5.enabled | false | 允许 Feign 使用 Apache HTTP Client 5。 |
| feign.httpclient.hc5.pool-concurrency-policy | 池并发策略。 | |
| feign.httpclient.hc5.pool-reuse-policy | 池连接重用策略。 | |
| feign.httpclient.hc5.socket-timeout | 5 | Socket超时的默认值。 |
| feign.httpclient.hc5.socket-timeout-unit | Socket超时单位的默认值。 | |
| feign.httpclient.max-connections | 200 | |
| feign.httpclient.max-connections-per-route | 50 | |
| feign.httpclient.time-to-live | 900 | |
| feign.httpclient.time-to-live-unit | ||
| feign.metrics.enabled | true | 为 Feign 启用指标功能。 |
| feign.okhttp.enabled | false | 允许 Feign 使用 OK HTTP Client。 |
参考:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/



