feign 使用基础
概述
Feign 是一个轻量级的 HTTP 请求调用框架,可以通过 Java 接口注解的方式进行 HTTP 请求。Feign 通过注解处理,将请求模板化。在实际调用时,传入参数,并根据参数应用到请求上,最终转化为真正的请求。该框架封装了 HTTP 调用流程,让其更加简单易用。
一、架构说明
参考 新增微服务完成 CRUD,在操作时会新建一个包含两个模块的 Maven 微服务业务模块。
x
├── x-api # api 模块主要存放实体、feign 调用接口
└── x-biz # biz 模块主要存放具体的业务实现,其他模块不能直接导入
如上图所示,"服务调用方 X" 调用 "服务提供方 upms" 的相关接口。因此,"X" 服务需要引入 upms-api 的 Maven 模块。
⚠模块引入注意事项
引入的是服务提供方的 API 模块,而不是引入 BIZ 模块。
二、FeignClient 定义
定义示例
以 upms 模块为例,展示如何定义 Feign 调用:
package com.pig4cloud.pigx.admin.api.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* Feign 客户端示例
*/
@FeignClient(contextId = "remoteUserService", value = "pigx-upms")
public interface RemoteUserService {
/**
* 根据用户ID获取用户信息
* @param id 用户ID
* @return 用户信息
*/
@GetMapping("/user/info/{id}")
R getUserInfo(@PathVariable("id") Long id);
}
关键要点
- 模块位置:FeignClient 必须定义在 API 模块 中。如果服务提供方没有 API 模块(例如 mp/pay 等模块),则需要自己创建对应的 Maven API 模块,参考 upms-api 即可。
- contextId 属性:代表 Bean 名称,在整个工程中必须唯一,避免命名冲突。
- value 属性:代表服务提供方的名称(即注册中心的服务名)。
- Mapping 路径:对应服务提供方接口路径(服务提供接口的 Controller Mapping + 接口 Mapping)。
三、SPI 文件声明
将 FeignClient 所属类的全路径配置在 META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports 文件中:
com.pig4cloud.pigx.admin.api.feign.RemoteUserService
com.pig4cloud.pigx.admin.api.feign.RemoteDeptService
⚠SPI配置重要性
虽然框架会自动扫描 com.pig4cloud.pigx 包下的所有 FeignClient,但在部分情况下,由于包名定义不规范,可能会导致 FeignClient 无法被扫描到,非常难以排查。因此,将 FeignClient 配置在 Spring SPI 文件中,可以确保在任何情况下都能正确加载相应的 FeignClient。
四、Feign 超时配置
默认配置说明
Feign 默认的超时配置通常已经能够满足大部分业务场景的需求,不推荐通过全局配置文件覆盖所有接口的超时时间。
针对特殊接口的超时配置
对于少数需要更长处理时间的接口(如文件上传、大数据量导出等),推荐使用 方法级别的超时配置:
方式一:在调用时传入 Options 参数
import feign.Request;
import java.util.concurrent.TimeUnit;
// 创建自定义超时配置
Request.Options options = new Request.Options(
5L, TimeUnit.SECONDS, // 连接超时时间
120L, TimeUnit.SECONDS, // 读取超时时间
true // 是否遵循重定向
);
// 调用时传入 options
remoteFileService.uploadLargeFile(file, options);
方式二:在 FeignClient 接口中定义
@FeignClient
public interface RemoteFileService {
/**
* 普通文件上传 - 使用默认超时配置
*/
@PostMapping("/file/upload")
R uploadFile(@RequestPart("file") MultipartFile file);
/**
* 大文件上传 - 自定义超时配置
* @param file 文件
* @param options 超时配置
*/
@PostMapping("/file/upload/large")
R uploadLargeFile(@RequestPart("file") MultipartFile file, Request.Options options);
/**
* 数据导出 - 自定义超时配置
* @param query 查询条件
* @param options 超时配置
*/
@PostMapping("/data/export")
R exportData(@RequestBody DataQuery query, Request.Options options);
}
配置参数说明
| 参数 | 说明 | 默认值 | 推荐值 |
|---|
| connectTimeout | 连接超时时间 | 10秒 | 5-10秒 |
| readTimeout | 读取超时时间 | 60秒 | 根据业务调整 |
| followRedirects | 是否遵循重定向 | true | true |
最佳实践建议
💡超时配置原则
大多数接口使用默认超时配置即可,无需额外配置。仅对文件上传/下载、大数据量查询、复杂报表生成、第三方接口调用等特殊场景考虑自定义超时。
- 保持默认配置:大多数接口使用默认超时配置即可,无需额外配置。
- 识别特殊场景:仅对以下场景考虑自定义超时:
- 文件上传/下载
- 大数据量查询
- 复杂报表生成
- 第三方接口调用
- 合理设置时间:根据实际业务需求设置超时时间,避免设置过长导致资源浪费。
- 添加注释说明:在代码中注释说明为什么需要自定义超时配置。
- 监控和调优:通过监控观察接口响应时间,适时调整超时配置。