题目
设计支持多级重试和熔断机制的自定义异常处理框架
信息
- 类型:问答
- 难度:⭐⭐⭐
考点
自定义异常设计,异常传播控制,重试策略实现,资源安全清理,熔断机制集成
快速回答
实现要点:
- 创建带错误分类的自定义异常体系
- 使用责任链模式实现多级重试策略(立即重试/延迟重试)
- 通过熔断器模式防止级联故障
- 确保重试过程中的资源安全和线程安全
- 利用finally块和try-with-resources保障资源释放
核心设计原理
在分布式系统中,需要处理网络抖动、服务暂时不可用等场景。本框架需实现:
- 异常分类体系:区分可重试异常(如网络超时)和不可重试异常(如验证失败)
- 重试策略:支持指数退避、固定间隔等多级重试逻辑
- 熔断机制:当失败率超过阈值时自动熔断,避免雪崩效应
- 资源安全:确保重试过程中资源不被泄露
代码实现示例
// 1. 自定义异常体系
public class RetryableException extends Exception {
private final ErrorType errorType; // 枚举: NETWORK, SERVER_UNAVAILABLE等
}
// 2. 熔断器实现
public class CircuitBreaker {
private int failureThreshold;
private long resetTimeout;
private volatile State state = State.CLOSED;
enum State { CLOSED, OPEN, HALF_OPEN }
public void execute(Runnable task) throws CircuitOpenException {
if (state == State.OPEN) throw new CircuitOpenException();
try {
task.run();
recordSuccess();
} catch (Exception e) {
recordFailure();
throw e;
}
}
}
// 3. 重试执行器(核心)
public class RetryExecutor {
private final CircuitBreaker circuitBreaker;
public <T> T execute(RetryCallable<T> callable, int maxAttempts)
throws Exception {
int attempt = 0;
while (attempt < maxAttempts) {
try (Resource resource = acquireResource()) { // 自动资源管理
circuitBreaker.execute(() -> {
return callable.call(resource); // 业务逻辑执行
});
break;
} catch (RetryableException e) {
if (++attempt >= maxAttempts) throw e;
Thread.sleep(calculateBackoff(attempt)); // 指数退避
} catch (NonRetryableException e) {
throw e; // 直接抛出不可重试异常
}
}
}
}最佳实践
- 异常分类:明确区分业务异常(不可重试)和系统异常(可重试)
- 资源清理:使用try-with-resources确保每次重试都重新获取资源
- 线程安全:熔断器状态使用volatile+CAS操作保证可见性
- 监控集成:记录重试次数和熔断状态用于系统监控
常见错误
| 错误类型 | 后果 | 解决方案 |
|---|---|---|
| 未重置重试状态 | 导致无限重试 | 设置最大尝试次数+熔断超时 |
| 资源未释放 | 连接泄漏/内存溢出 | 在finally块中清理或使用try-with-resources |
| 忽略InterruptedException | 无法响应线程中断 | 恢复中断状态:Thread.currentThread().interrupt() |
扩展知识
- 退避算法:指数退避(Exponential Backoff)增加随机抖动避免惊群效应
- 熔断恢复策略:半开状态允许部分请求试探服务恢复
- 异步重试:结合CompletableFuture实现非阻塞重试
- 框架集成:Spring Retry的@Retryable注解底层原理