Feign 远程调用
先来看我们以前利用 RestTemplate 发起远程调用的代码:

存在下面的问题:
- 代码可读性差,编程体验不统一
- 参数复杂 URL 难以维护
Feign 是一个声明式的 http 客户端,官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现 http 请求的发送,解决上面提到的问题。

Feign 替代 RestTemplate
Feign 的使用步骤如下:
1)引入依赖
我们在 order-service 服务的 pom 文件中引入 feign 的依赖:
1 | <dependency> |
2)添加注解
在 order-service 的启动类添加注解开启 Feign 的功能:

3)编写 Feign 的客户端
在 order-service 中新建一个接口,内容如下:
1 | package cn.itcast.order.client; |
这个客户端主要是基于 Spring MVC 的注解来声明远程调用的信息,比如:
- 服务名称:userservice
- 请求方式:GET
- 请求路径:/user/{id}
- 请求参数:Long id
- 返回值类型:User
这样,Feign 就可以帮助我们发送 http 请求,无需自己使用 RestTemplate 来发送了。
4)测试
修改 order-service 中的 OrderService 类中的 queryOrderById 方法,使用 Feign 客户端代替 RestTemplate:

5)总结
使用 Feign 的步骤:
- 引入依赖
- 添加
@EnableFeignClients注解 - 编写
FeignClient接口 - 使用
FeignClient中定义的方法代替 RestTemplate
自定义配置
Feign 可以支持很多的自定义配置,如下表所示:
| 类型 | 作用 | 说明 |
|---|---|---|
| feign.Logger.Level | 修改日志级别 | 包含四种不同的级别:NONE、BASIC、HEADERS、FULL |
| feign.codec.Decoder | 响应结果的解析器 | http 远程调用的结果做解析,例如解析 json 字符串为 java 对象 |
| feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过 http 请求发送 |
| feign.Contract | 支持的注解格式 | 默认是 Spring MVC 的注解 |
| feign.Retryer | 失败重试机制 | 请求失败的重试机制,默认是没有,不过会使用 Ribbon 的重试 |
一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的 @Bean 覆盖默认 Bean 即可。
下面以日志为例来演示如何自定义配置。
配置文件方式
基于配置文件修改 feign 的日志级别可以针对单个服务:
1 | feign: |
也可以针对所有服务:
1 | feign: |
而日志的级别分为四种:
- NONE:不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL 以及响应状态码和执行时间
- HEADERS:在 BASIC 的基础上,额外记录了请求和响应的头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
Java 代码方式
也可以基于 Java 代码来修改日志级别,先声明一个类,然后声明一个 Logger.Level 的对象:
1 | public class DefaultFeignConfiguration { |
如果要全局生效,将其放到启动类的 @EnableFeignClients 这个注解中:
1 |
如果是局部生效,则把它放到对应的 @FeignClient 这个注解中:
1 |
Feign 使用优化
Feign 底层发起 http 请求,依赖于其它的框架。其底层客户端实现包括:
- URLConnection:默认实现,不支持连接池
- Apache HttpClient:支持连接池
- OKHttp:支持连接池
因此提高 Feign 的性能主要手段就是使用连接池代替默认的 URLConnection。
这里我们用 Apache 的 HttpClient 来演示。
1)引入依赖
在 order-service 的 pom 文件中引入 Apache 的 HttpClient 依赖:
1 | <!--httpClient的依赖 --> |
2)配置连接池
在 order-service 的 application.yml 中添加配置:
1 | feign: |
接下来,在 FeignClientFactoryBean 中的 loadBalance 方法中打断点:

Debug 方式启动 order-service 服务,可以看到这里的 client,底层就是 Apache HttpClient:

总结
Feign 的优化:
- 日志级别尽量用 basic
- 使用 HttpClient 或 OKHttp 代替 URLConnection
- 引入 feign-httpClient 依赖
- 配置文件开启 httpClient 功能,设置连接池参数