Describe a scenario where a microservice might fail. How would you implement the Circuit Breaker pattern to handle failures and maintain system resilience?

A microservice can fail when a downstream dependency, like a Payment service, becomes slow or unavailable, and the Circuit Breaker pattern handles this by monitoring failures and temporarily blocking further calls to give the failing service time to recover.

Key Points: • Calls to the Payment service are wrapped in a circuit breaker that tracks the failure rate over a rolling window of recent calls. • Once failures exceed a configured threshold, the circuit opens, and further calls fail immediately with a fallback instead of waiting on timeouts. • This prevents cascading failure, since the Order service's threads aren't tied up waiting on a Payment service that's already struggling. • After a cooldown period, the breaker allows a small number of trial requests through in a half-open state to check whether Payment has recovered. • If those trial requests succeed, the circuit closes and normal traffic resumes; if they fail, it reopens and waits longer before trying again.

Example: If the Payment service starts timing out under load, the circuit breaker around it opens after five consecutive failures, and the Order service immediately returns a "payment temporarily unavailable, please retry" response instead of hanging on every checkout request until it times out.

Code Example:

@CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")
public PaymentResponse charge(PaymentRequest request) {
    return paymentClient.charge(request);
}

public PaymentResponse paymentFallback(PaymentRequest request, Throwable t) {
    return PaymentResponse.unavailable();
}

Interview Tip: A concise interview answer is:

"If a dependency like Payment starts failing, I'd wrap calls to it in a circuit breaker that opens once failures cross a threshold, failing fast with a fallback instead of piling up timeouts. After a cooldown it tests recovery with a few trial requests before fully closing again, which keeps one failing service from cascading into the whole order flow."