本文目录导读:

接口熔断机制是一种防止服务雪崩的自我保护策略,通常通过熔断框架(如 Hystrix、Resilience4j、Sentinel)来实现。
要实现接口熔断,需要在项目中引入相应的库,并对其进行配置,以下是基于目前主流的 Resilience4j(Spring Cloud 官方推荐)和 Sentinel(阿里系常用)的两种开启方式详解。
核心原理
熔断器主要有三个状态:
- Closed(关闭):正常状态,请求通过。
- Open(打开):当失败率达到阈值,熔断器打开,直接拒绝请求(快速失败)。
- Half-Open(半开):经过一段时间(等待窗口)后,允许少量请求尝试,如果成功,则关闭熔断器;如果失败,则继续保持打开。
使用 Resilience4j(Spring Boot 项目)
这是目前 Spring Cloud 的最新生态推荐方案(替代了已停更的 Hystrix)。
引入依赖
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>最新版本</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
配置文件
在 application.yml 中定义熔断器规则(以调用 userService 接口为例):
resilience4j:
circuitbreaker:
configs:
default:
# 熔断器关闭时,请求数超过该值才开始计算失败率
sliding-window-size: 10
# 最小请求数(防止起始阶段波动大)
minimum-number-of-calls: 5
# 失败率达到 50% 时开启熔断
failure-rate-threshold: 50
# 熔断开启后,等待 10 秒尝试进入半开状态
wait-duration-in-open-state: 10s
# 半开状态下允许通过的请求数
permitted-number-of-calls-in-half-open-state: 3
# 记录异常的滑动窗口类型(基于时间或计数)
sliding-window-type: COUNT_BASED
instances:
# 自定义熔断器名称,用于绑定接口
userServiceApi:
base-config: default
业务代码中使用
在需要保护的 Service 或 Controller 方法上添加 @CircuitBreaker 注解:
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
@Service
public class UserService {
// name 对应配置文件中的熔断器实例名称
// fallbackMethod 指定熔断后调用的备用方法
@CircuitBreaker(name = "userServiceApi", fallbackMethod = "getUserFallback")
public User getUserById(Long id) {
// 这里调用远程接口(可能失败)
return restTemplate.getForObject("http://remote-service/user/" + id, User.class);
}
// 备用方法:返回默认值或兜底数据(注意参数和返回值要匹配)
public User getUserFallback(Long id, Throwable t) {
return new User("默认用户");
}
}
使用 Sentinel(阿里系,功能更强)
Sentinel 除了熔断,还支持限流、系统保护等,配置方式分为控制台和代码两种。
引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
配置文件
spring:
cloud:
sentinel:
enabled: true
transport:
# 连接 Sentinel 控制台(可选,简化情况下可以不用)
dashboard: localhost:8080
# 熔断规则可以写死在代码中,也可以通过控制台推送
代码配置熔断规则(核心方式)
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@Component
public class SentinelConfig {
@PostConstruct
public void initDegradeRule() {
// 创建熔断规则列表
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
// 资源名称(必须与要保护的接口名一致)
rule.setResource("getUserById");
// 熔断策略:1 表示平均响应时间(RT),0 表示异常比例
rule.setGrade(0);
// 异常比例阈值:0.5 表示 50%
rule.setCount(0.5);
// 触发熔断的最小请求数
rule.setMinRequestAmount(5);
// 统计时长(单位:毫秒)
rule.setStatIntervalMs(1000);
// 熔断后恢复的时间(秒)
rule.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
}
业务代码中使用
import com.alibaba.csp.sentinel.annotation.SentinelResource;
@Service
public class UserService {
// value 必须与上面规则的 resource 一致
@SentinelResource(value = "getUserById", fallback = "getUserFallback")
public User getUserById(Long id) {
// 业务逻辑
return remoteClient.getUser(id);
}
public User getUserFallback(Long id, Throwable e) {
return new User("降级用户");
}
}
手动实现一个简单的熔断器(不依赖框架)
如果项目过于老旧或不想引入外部框架,可以基于状态机手动实现(原理参考):
@Component
public class SimpleCircuitBreaker {
private AtomicInteger failureCount = new AtomicInteger(0);
private AtomicInteger successCount = new AtomicInteger(0);
private volatile CircuitBreakerState state = CircuitBreakerState.CLOSED;
private long lastFailureTime;
private final int threshold = 5; // 失败次数阈值
private final long timeout = 5000; // 半开恢复窗口(毫秒)
public boolean allowRequest() {
switch (state) {
case OPEN:
// 检查时间窗口是否已到,尝试半开
if (System.currentTimeMillis() - lastFailureTime > timeout) {
state = CircuitBreakerState.HALF_OPEN;
return true;
}
return false;
case HALF_OPEN:
return true;
default:
return true;
}
}
public void recordSuccess() {
if (state == CircuitBreakerState.HALF_OPEN) {
// 半开后成功,则关闭熔断器
state = CircuitBreakerState.CLOSED;
failureCount.set(0);
successCount.set(0);
} else if (state == CircuitBreakerState.CLOSED) {
// 按需实现滑动窗口
}
}
public void recordFailure() {
if (state == CircuitBreakerState.HALF_OPEN) {
state = CircuitBreakerState.OPEN;
lastFailureTime = System.currentTimeMillis();
} else if (state == CircuitBreakerState.CLOSED) {
failureCount.incrementAndGet();
if (failureCount.get() >= threshold) {
state = CircuitBreakerState.OPEN;
lastFailureTime = System.currentTimeMillis();
}
}
}
enum CircuitBreakerState {
OPEN, HALF_OPEN, CLOSED
}
}
使用时,在调用接口前后调用 allowRequest、recordSuccess、recordFailure 即可。
如何选择?
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| Spring Boot / Cloud 新项目 | Resilience4j | 轻量、无外部依赖、官方维护 |
| 需要强大的限流、熔断、监控 | Sentinel | 控制台可视化、动态规则、支持热点参数 |
| 旧项目、不想加依赖 | 手动实现 | 高度定制、简单场景够用 |
| 已经用 Feign 调用接口 | Resilience4j + Feign | 配合 @FeignClient 的 fallback 属性,配置更简单 |
关键操作步骤通用逻辑:
- 引入框架依赖。
- 定义熔断阈值(失败比例、响应时间、错误数量)。
- 定义熔断恢复策略(等待多久尝试恢复)。
- 在业务方法上标注注解或配置资源点。
- 提供降级方法(fallback),作为熔断后的备用逻辑。
标签: Sentinel
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播