目录
5.2 高级降级:Resilience4j(fallbackFactory)
简要概述
Spring Cloud OpenFeign 是对 Netflix Feign 的二次封装,提供了声明式的 HTTP 客户端,让我们可以通过定义接口并添加注解的方式,像调用本地方法一样发起远程服务调用,同时支持 Spring MVC 注解(如 @GetMapping
, @PostMapping
)及与 Ribbon、Circuit Breaker、LoadBalancer 的无缝集成。它通过 @EnableFeignClients
注解触发对所有标注了 @FeignClient
接口的扫描与注册,并在运行时利用 FeignClientFactoryBean
生成代理对象,实现负载均衡与容错CSDN 博客。OpenFeign 的核心优势在于:极大简化了远程调用代码、提供了可插拔的编码器/解码器、支持 Hystrix 熔断与断路器、并且允许用户通过配置自定义拦截器、超时、日志等策略博客园。
1. 引入依赖与初始化
Maven/Gradle 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
-
spring-cloud-starter-openfeign
提供了 Feign 客户端支持。 -
spring-cloud-starter-loadbalancer
使 OpenFeign 可以使用 Spring Cloud LoadBalancer 进行客户端负载均衡。
启用注解
在 Spring Boot 启动类上添加:
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
-
@EnableFeignClients
扫描并注册所有@FeignClient
接口。
2. 定义 Feign 客户端接口
@FeignClient(
name = "user-service",
path = "/user",
url = "${user.service.url}",
fallbackFactory = UserClientFallbackFactory.class,
configuration = CustomFeignConfig.class
)
public interface UserClient {
@GetMapping("/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
@PostMapping("/create")
UserDTO createUser(@RequestBody CreateUserRequest req);
}
-
name
: 服务在注册中心的名称。 -
path
与url
:可选,path
用于公共前缀,url
可硬编码或通过配置注入。 -
fallbackFactory
:用于服务降级,能获取调用异常信息。 -
configuration
:指定自定义的 Feign 配置(拦截器、日志、编码器等)。
3. 核心注解与原理
-
@EnableFeignClients
通过引入FeignClientsRegistrar
,实现对@FeignClient
的扫描和FeignClientFactoryBean
的注册。 -
FeignClientFactoryBean
在容器启动阶段,为每个@FeignClient
接口创建代理,通过动态代理方式实现远程调用。
4. 配置项与高级特性
4.1 超时与重试
在 application.yml
中配置:
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 10000
retryer:
# 重试三次,每次间隔 100ms
period: 100
maxPeriod: 100
maxAttempts: 3
-
connectTimeout
与readTimeout
用于连接与读取超时。citeturn0search7 -
retryer
控制重试逻辑。
4.2 负载均衡与熔断
-
Ribbon:OpenFeign 内置 Ribbon 做客户端负载均衡,可进一步配置负载均衡策略。
-
Hystrix / Resilience4j:可通过
feign.hystrix.enabled=true
使用 Hystrix 熔断;Spring Cloud 2020+ 倾向于使用 Resilience4j。
4.3 拦截器与日志
自定义 Feign 拦截器:
@Configuration
public class CustomFeignConfig {
@Bean
public RequestInterceptor authInterceptor() {
return template -> template.header("Authorization", "Bearer " + fetchToken());
}
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
-
RequestInterceptor
实现请求前的统一处理,如鉴权。 -
Logger.Level
控制 Feign 日志级别。
5. 降级与容错
5.1 简单降级:Hystrix(fallback)
【1】引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
-
Spring Cloud 2020 之前:
feign.hystrix.enabled=true
即可启用 Hystrix 熔断。 -
Spring Cloud 2020 及以后:需改为
feign.circuitbreaker.enabled=true
并确保引入 Hystrix 依赖。
【2】yml配置
# application.yml
feign:
hystrix:
enabled: true
# 或者(2020+ 版本)
feign:
circuitbreaker:
enabled: true
【3】启动类添加注解
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class Application { … }
【4】示例
@FeignClient(name = "user-service", fallback = UserFallback.class)
public interface UserClient {
@GetMapping("/user/{id}")
UserDTO getById(@PathVariable Long id);
}
@Component
public class UserFallback implements UserClient {
@Override
public UserDTO getById(Long id) {
return new UserDTO(-1L, "default");
}
}
-
fallback
无法获取异常上下文,仅限于返回默认值。
5.2 高级降级:Resilience4j(fallbackFactory)
【1】引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
【2】yml配置
resilience4j:
timelimiter:
configs:
default:
timeout-duration: 10s #神坑的位置,timelimiter 默认限制远程1s,超于1s就超时异常,配置了降级,就走降级逻辑
circuitbreaker:
configs:
default:
failureRateThreshold: 50 #设置50%的调用失败时打开断路器,超过失败请求百分⽐CircuitBreaker变为OPEN状态。
slowCallDurationThreshold: 2s #慢调用时间阈值,高于这个阈值的视为慢调用并增加慢调用比例。
slowCallRateThreshold: 30 #慢调用百分比峰值,断路器把调用时间⼤于slowCallDurationThreshold,视为慢调用,当慢调用比例高于阈值,断路器打开,并开启服务降级
slidingWindowType: TIME_BASED # 滑动窗口的类型
slidingWindowSize: 2 #滑动窗口的大小配置,配置TIME_BASED表示2秒
minimumNumberOfCalls: 2 #断路器计算失败率或慢调用率之前所需的最小样本(每个滑动窗口周期)。
permittedNumberOfCallsInHalfOpenState: 2 #半开状态允许的最大请求数,默认值为10。
waitDurationInOpenState: 5s #从OPEN到HALF_OPEN状态需要等待的时间
recordExceptions:
- java.lang.Exception
instances:
ms-provider:
baseConfig: default
【3】启动类添加注解
同Hystrix
【4】示例
@FeignClient(
name = "user-service",
fallbackFactory = UserFallbackFactory.class
)
public interface UserClient { … }
@Component
public class UserFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable cause) {
return id -> {
// 日志记录 cause.getMessage()
return new UserDTO(-1L, "resilience4j-default");
};
}
}
-
fallbackFactory
能捕获并处理异常,适合更复杂的降级逻辑。
6. 完整示例
6.1 服务提供者(User Service)
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/{id}")
public UserDTO getUser(@PathVariable Long id) {
return new UserDTO(id, "User" + id);
}
}
6.2 服务消费者(Order Service)
application.yml
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
feign:
client:
config:
default:
connectTimeout: 3000
readTimeout: 5000
启动类
@SpringBootApplication
@EnableFeignClients
public class OrderApplication { … }
Feign 客户端接口
@FeignClient(name = "user-service", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient { … }
业务调用
@Service
public class OrderService {
@Autowired private UserClient userClient;
public void placeOrder(Long userId) {
UserDTO user = userClient.getUserById(userId);
// 继续业务逻辑…
}
}
以上即 Spring Cloud OpenFeign 的核心使用、配置及最佳实践,通过依赖引入、注解驱动、配置管理、降级容错和日志拦截,能够帮助您快速、优雅地实现微服务之间的远程调用。
7.参考文章
Spring Cloud OpenFeign 的使用及踩坑指南 - 顔宸 - 博客园