외부 API 지연/장애 시 서버 자원 고갈과 연쇄 장애를 막기 위한 방어적 설계와 운영 전략을 정리합니다. Java/Spring 실무 예시 포함.
타임아웃은 지수 백오프+재시도와 곱으로 체감 지연을 초과하지 않도록 합리화하십시오.
# 예: Spring WebClient(reactor-netty) 커넥션 풀을 외부 서비스별로 분리
reactor.netty.pool.maxConnections: 100 # 서비스 A
reactor.netty.pool.pendingAcquireMaxCount: 50 # 대기 한도
# 서비스 B는 별도 HttpClient 인스턴스로 구성(풀이 분리됨)
// Resilience4j 예시
@CircuitBreaker(name = "svcA", fallbackMethod = "fallback")
public String callA(...) { ... }
@Bulkhead(name = "svcA-bulk", type = Bulkhead.Type.THREADPOOL)
@TimeLimiter(name = "svcA-tl")
public CompletableFuture<String> callAAsync(...) { ... }
임계값은 요청 수 최소 기준(sliding window)과 함께 설정하고, Slow Call Rate(예: > 1s)를 별도로 감지하십시오.
resilience4j.retry:
instances:
svcA:
maxAttempts: 3
waitDuration: 200ms
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2.0
retryExceptions:
- java.io.IOException
- java.net.SocketTimeoutException
stale-if-error). TTL/무효화 전략 포함.HttpClient clientA = HttpClient.create(ConnectionProvider.builder("svcA-pool")
.maxConnections(100)
.pendingAcquireMaxCount(50)
.pendingAcquireTimeout(Duration.ofMillis(200))
.build())
.responseTimeout(Duration.ofSeconds(2))
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 300);
WebClient webClientA = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(clientA))
.baseUrl("https://svc-a.example.com")
.build();
OkHttpClient clientA = new OkHttpClient.Builder()
.connectTimeout(300, TimeUnit.MILLISECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(50, 30, TimeUnit.SECONDS)) // A 전용 풀
.build();
resilience4j.circuitbreaker:
instances:
svcA:
slidingWindowType: COUNT_BASED
slidingWindowSize: 50
failureRateThreshold: 50
slowCallRateThreshold: 50
slowCallDurationThreshold: 1s
minimumNumberOfCalls: 20
waitDurationInOpenState: 10s
resilience4j.bulkhead:
instances:
svcA-bulk:
maxConcurrentCalls: 30
maxWaitDuration: 100ms
resilience4j.timelimiter:
instances:
svcA-tl:
timeoutDuration: 2s
@CircuitBreaker(name = "svcA", fallbackMethod = "fallback")
@Retry(name = "svcA")
@Bulkhead(name = "svcA-bulk")
public interface SvcAClient { ... }