可靠性设计
可靠性设计确保系统在出现故障时仍能正常运行。
📋 核心要素
- 容错设计:通过重试、超时、限流等机制保证系统可靠性
- 幂等性设计:保证操作的幂等性,避免重复操作
🎯 容错设计
容错设计策略:
重试机制实现
java
/**
* 重试工具类
*/
public class RetryUtil {
private static final int MAX_RETRIES = 3;
private static final long INITIAL_DELAY_MS = 1000;
/**
* 带重试的执行
*/
public static <T> T executeWithRetry(Supplier<T> operation) {
return executeWithRetry(operation, MAX_RETRIES, INITIAL_DELAY_MS);
}
/**
* 带重试的执行(自定义参数)
*/
public static <T> T executeWithRetry(Supplier<T> operation, int maxRetries, long initialDelayMs) {
int attempt = 0;
long delay = initialDelayMs;
while (attempt < maxRetries) {
try {
return operation.get();
} catch (Exception e) {
attempt++;
if (attempt >= maxRetries) {
throw new RetryExhaustedException("Max retries exceeded", e);
}
// 指数退避
try {
Thread.sleep(delay);
delay *= 2; // 指数退避
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RetryInterruptedException("Retry interrupted", ie);
}
}
}
throw new IllegalStateException("Should not reach here");
}
}🎯 幂等性设计
幂等性保证:
java
/**
* 幂等性接口
*/
public interface IdempotentService {
/**
* 幂等操作:使用唯一标识符保证幂等性
*/
OrderResult createOrder(OrderRequest request, String idempotentKey);
}
/**
* 幂等性实现
*/
@Service
public class OrderService implements IdempotentService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
@Transactional
public OrderResult createOrder(OrderRequest request, String idempotentKey) {
// 检查幂等性Key是否已使用
String existingOrderId = redisTemplate.opsForValue().get("idempotent:" + idempotentKey);
if (existingOrderId != null) {
// 已处理过,返回相同结果
Order order = orderRepository.findById(Long.parseLong(existingOrderId))
.orElseThrow();
return OrderResult.success(order);
}
// 使用数据库唯一约束保证幂等性
try {
// 创建订单
Order order = new Order();
order.setUserId(request.getUserId());
order.setAmount(request.getAmount());
order.setIdempotentKey(idempotentKey); // 唯一约束
order.setStatus(OrderStatus.PENDING);
order = orderRepository.save(order);
// 保存幂等性Key(24小时过期)
redisTemplate.opsForValue().set(
"idempotent:" + idempotentKey,
order.getId().toString(),
24,
TimeUnit.HOURS
);
return OrderResult.success(order);
} catch (DataIntegrityViolationException e) {
// 唯一约束冲突,说明订单已存在
Order existingOrder = orderRepository.findByIdempotentKey(idempotentKey)
.orElseThrow();
return OrderResult.success(existingOrder);
}
}
}