由于 RestTemplate 方式调用存在以下问题:
- 代码可读性差,编程体验不统一
- 参数复杂 URL 难以维护
======> 使用 Feign 可以解决上面的问题
Feign 的介绍
Feign 是一个声明式的 HTTP 客户端,其作用就是实现 HTTP 请求的发送
定义和使用 Feign 客户端
1. 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.5</version>
</dependency>
2. 在启动类添加注解开启 Feign 的功能
@EnableFeignClients
@SpringBootApplication
public class CloudDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CloudDemoApplication.class, args);
}
}
3. 编写 FeignClient 接口
public interface UserAPI {
@GetMapping("/user/{id}")
Result getById(@PathVariable Long id);
}
@FeignClient("userservice") # 请求服务名称
public interface UserClient extends UserAPI{}
4. 使用 FeignClient 代替 RestTemplate 实现远程调用
// 此场景为订单模块远程调用用户模块实现查询订单用户信息
@Service
public class OrderService {
@Resource
private OrderMapper orderMapper;
@Resource
private UserClient userClient;
public Order getOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.基于 Feign 远程调用
User user = userClient.findById(order, getUserId());
// 3.封装 user 到 Order
order.setUser(user);
// 4.返回
return order;
}
}
自定义 Feign 的配置
Feign 运行自定义配置来覆盖默认配置,可以修改的配置如下:
类型 | 作用 | 说明 |
---|---|---|
feign.Logger.Level | 修改日志级别 | 包含四种不同的级别:NONE、BASIC、HEADERS、FULL |
feign.codec.Decoder | 响应结果的解析器 | HTTP远程调用的结果做解析,例如解析JSON字符串为JAVA对象 |
feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过 HTTP 请求发送 |
feign.Contract | 支持的注解格式 | 默认是SpringMVC的注解 |
feign.Retryer | 失败重试机制 | 请求失败的重试机制,默认是没有,不过会使用Ribbon的重试 |
一般我们只需要配置日志级别
Feign 的性能优化
Feign 底层的客户端实现
- URLConnection(默认): 不支持连接池
- Apache HttpClient: 支持连接池
- OKHttp: 支持连接池
因此优化 Feign 的性能主要包括:
- 使用连接池代替默认的 URLConnection
- 日志级别最好用 BASIC 或 NONE
连接池配置
Feign 添加 HttpClient 的支持
<!-- 引入依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
# 配置日志级别
feign:
client:
config:
default: # default 全局配置
loggerLevel: BASIC # 日志级别
httpclient: # 配置连接池
enabled: true # 开启 feign 对 HttpClient 的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数