← 返回首页
🛡️

韧性模式

📂 architecture ⏱ 2 min 314 words

韧性模式

舱壁隔离

舱壁模式(Bulkhead)源自船舶设计,将系统划分为多个隔离区域,一个区域的故障不会影响其他区域。

// 基于线程池的舱壁隔离
@Component
public class BulkheadService {
    
    private final ExecutorService paymentPool;
    private final ExecutorService queryPool;
    private final ExecutorService notificationPool;
    
    @PostConstruct
    public void init() {
        // 支付服务独立线程池
        paymentPool = new ThreadPoolExecutor(
            10, 20, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
        
        // 查询服务独立线程池
        queryPool = new ThreadPoolExecutor(
            20, 50, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(500),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
        
        // 通知服务独立线程池
        notificationPool = new ThreadPoolExecutor(
            5, 10, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(200),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
    
    public CompletableFuture<PaymentResult> processPayment(PaymentRequest request) {
        return CompletableFuture.supplyAsync(
            () -> paymentService.process(request), paymentPool);
    }
    
    public CompletableFuture<List<Product>> queryProducts(QueryRequest request) {
        return CompletableFuture.supplyAsync(
            () -> productService.query(request), queryPool);
    }
}

超时与重试

超时控制防止请求长时间阻塞,重试机制处理临时性故障。

// 超时重试配置
@Component
public class ResilientClient {
    
    private final RetryConfig retryConfig = RetryConfig.custom()
        .maxAttempts(3)
        .waitDuration(Duration.ofMillis(500))
        .retryExceptions(ConnectException.class, TimeoutException.class)
        .ignoreExceptions(BusinessException.class)
        .build();
    
    private final CircuitBreakerConfig circuitConfig = CircuitBreakerConfig.custom()
        .failureRateThreshold(50)
        .waitDurationInOpenState(Duration.ofSeconds(10))
        .slidingWindowSize(10)
        .build();
    
    public String callExternalService(String request) {
        Retry retry = Retry.of("externalService", retryConfig);
        CircuitBreaker circuitBreaker = CircuitBreaker.of("externalService", circuitConfig);
        
        Supplier<String> decoratedSupplier = Decorators.ofSupplier(
                () -> doCallExternalService(request))
            .withCircuitBreaker(circuitBreaker)
            .withRetry(retry)
            .withTimeout(Duration.ofSeconds(5))
            .decorate();
        
        return Try.ofSupplier(decoratedSupplier)
            .recover(TimeoutException.class, e -> fallbackResponse())
            .get();
    }
}

熔断器模式

熔断器在故障率达到阈值时停止调用故障服务,防止级联故障。

// 状态机实现的熔断器
public class CircuitBreaker {
    
    public enum State { CLOSED, OPEN, HALF_OPEN }
    
    private State state = State.CLOSED;
    private int failureCount = 0;
    private int successCount = 0;
    private final int failureThreshold;
    private final Duration openDuration;
    private LocalDateTime openedAt;
    
    public CircuitBreaker(int failureThreshold, Duration openDuration) {
        this.failureThreshold = failureThreshold;
        this.openDuration = openDuration;
    }
    
    public synchronized <T> T execute(Supplier<T> action, Supplier<T> fallback) {
        if (state == State.OPEN) {
            if (LocalDateTime.now().isAfter(openedAt.plus(openDuration))) {
                state = State.HALF_OPEN;
            } else {
                return fallback.get();
            }
        }
        
        try {
            T result = action.get();
            onSuccess();
            return result;
        } catch (Exception e) {
            onFailure();
            return fallback.get();
        }
    }
    
    private void onSuccess() {
        if (state == State.HALF_OPEN) {
            successCount++;
            if (successCount >= 3) {
                state = State.CLOSED;
                failureCount = 0;
                successCount = 0;
            }
        } else {
            failureCount = 0;
        }
    }
    
    private void onFailure() {
        failureCount++;
        if (failureCount >= failureThreshold) {
            state = State.OPEN;
            openedAt = LocalDateTime.now();
        }
    }
}

韧性模式的组合使用能够有效提升系统在面对部分故障时的整体可用性。