Eureka与Feign集成
2026/1/15大约 3 分钟EurekaFeignOpenFeign
Eureka 与 Feign 集成
一、Feign 简介
Feign 是一个声明式的 HTTP 客户端,使用注解方式定义接口,自动实现服务调用。
1.1 RestTemplate vs Feign
// RestTemplate 方式
String url = "http://user-service/user/" + id;
User user = restTemplate.getForObject(url, User.class);
// Feign 方式
User user = userClient.getUser(id);1.2 Feign 特点
- 声明式接口定义
- 自动集成 Ribbon 负载均衡
- 支持 Hystrix 熔断
- 支持请求压缩
- 支持日志输出
二、快速开始
2.1 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>2.2 启用 Feign
@SpringBootApplication
@EnableFeignClients // 启用 Feign
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}2.3 定义 Feign 接口
@FeignClient(name = "user-service") // 指定服务名
public interface UserClient {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
@GetMapping("/user/list")
List<User> listUsers();
@PostMapping("/user")
User createUser(@RequestBody User user);
@PutMapping("/user/{id}")
User updateUser(@PathVariable("id") Long id, @RequestBody User user);
@DeleteMapping("/user/{id}")
void deleteUser(@PathVariable("id") Long id);
}2.4 使用 Feign 客户端
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private UserClient userClient;
@GetMapping("/{id}")
public Order getOrder(@PathVariable Long id) {
// 直接调用 Feign 接口
User user = userClient.getUser(id);
Order order = new Order();
order.setId(id);
order.setUser(user);
return order;
}
}三、Feign 配置
3.1 超时配置
feign:
client:
config:
default: # 全局配置
connectTimeout: 5000
readTimeout: 10000
user-service: # 针对特定服务
connectTimeout: 3000
readTimeout: 50003.2 日志配置
feign:
client:
config:
default:
loggerLevel: FULL # NONE, BASIC, HEADERS, FULL
logging:
level:
com.example.client: DEBUG日志级别说明:
| 级别 | 说明 |
|---|---|
| NONE | 不记录日志 |
| BASIC | 记录请求方法、URL、响应状态码、执行时间 |
| HEADERS | 记录 BASIC + 请求/响应头 |
| FULL | 记录 HEADERS + 请求/响应体 |
3.3 配置类方式
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
public Request.Options options() {
return new Request.Options(5000, 10000);
}
}四、请求拦截器
4.1 添加请求头
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 添加认证头
template.header("Authorization", "Bearer " + getToken());
// 添加追踪ID
template.header("X-Trace-Id", UUID.randomUUID().toString());
}
private String getToken() {
// 从上下文获取 token
return "your-token";
}
}4.2 传递请求头
@Component
public class FeignHeaderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes)
RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
// 传递原始请求的 Authorization 头
String auth = request.getHeader("Authorization");
if (auth != null) {
template.header("Authorization", auth);
}
}
}
}五、Feign 与 Hystrix 集成
5.1 启用 Hystrix
feign:
hystrix:
enabled: true5.2 定义降级类
@Component
public class UserClientFallback implements UserClient {
@Override
public User getUser(Long id) {
User user = new User();
user.setId(id);
user.setName("默认用户");
return user;
}
@Override
public List<User> listUsers() {
return Collections.emptyList();
}
@Override
public User createUser(User user) {
return null;
}
@Override
public User updateUser(Long id, User user) {
return null;
}
@Override
public void deleteUser(Long id) {
// 降级处理
}
}5.3 配置降级
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
// ...
}5.4 获取异常信息
@Component
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable cause) {
return new UserClient() {
@Override
public User getUser(Long id) {
// 可以记录异常信息
log.error("调用 user-service 失败: {}", cause.getMessage());
return new User();
}
// ...
};
}
}
@FeignClient(name = "user-service", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
// ...
}六、请求压缩
6.1 配置压缩
feign:
compression:
request:
enabled: true
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
response:
enabled: true七、继承特性
7.1 定义公共接口
// 公共模块
public interface UserApi {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
@PostMapping("/user")
User createUser(@RequestBody User user);
}7.2 服务提供者实现
@RestController
public class UserController implements UserApi {
@Override
public User getUser(Long id) {
// 实现逻辑
}
@Override
public User createUser(User user) {
// 实现逻辑
}
}7.3 Feign 客户端继承
@FeignClient(name = "user-service")
public interface UserClient extends UserApi {
// 自动继承父接口的方法定义
}八、多参数请求
8.1 GET 请求多参数
@FeignClient(name = "user-service")
public interface UserClient {
// 方式1:@RequestParam
@GetMapping("/user/search")
List<User> search(@RequestParam("name") String name,
@RequestParam("age") Integer age);
// 方式2:@SpringQueryMap
@GetMapping("/user/search")
List<User> search(@SpringQueryMap UserQuery query);
}8.2 POST 请求
@FeignClient(name = "user-service")
public interface UserClient {
// JSON 请求体
@PostMapping("/user")
User createUser(@RequestBody User user);
// 表单请求
@PostMapping(value = "/user/form", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
User createUserByForm(@RequestParam("name") String name,
@RequestParam("age") Integer age);
}九、总结
核心要点:
- 声明式调用:使用注解定义接口
- 自动负载均衡:集成 Ribbon
- 熔断降级:集成 Hystrix
- 灵活配置:超时、日志、压缩等
