문제 상황
Cloudflare Turnstile 봇 방어 기능을 인증 페이지에 적용한 뒤, Cloudflare 서버 장애 발생 시 응답을 기다리다 로그인 자체가 불가능해지는 상황이 발생했습니다.
원인 분석
외부 서비스 호출 시 타임아웃 설정이 없었고, Turnstile 검증 실패를 곧바로 로그인 실패로 처리하는 로직이 문제였습니다. 외부 서비스의 가용성이 내 서비스의 가용성을 직접 결정하는 구조였습니다.
Fallback 설계 원칙
외부 서비스 호출에는 반드시 타임아웃 + Fallback 처리를 함께 설계해야 합니다. 장애 상황에서 기능을 어느 수준까지 허용할지 명확히 정의하는 것이 핵심입니다.
// Turnstile 검증 with Fallback
fun verifyTurnstile(token: String): Boolean {
return try {
turnstileClient.verify(token, timeout = 2.seconds)
} catch (e: TimeoutException) {
log.warn("Turnstile timeout — applying fallback policy")
fallbackPolicy.allow()
}
}
Circuit Breaker 적용
Resilience4j의 Circuit Breaker를 적용해 연속 실패 임계치 초과 시 자동으로 Open 상태로 전환되도록 했습니다. Open 상태에서는 외부 호출을 건너뛰고 즉시 Fallback을 실행합니다.
결과 및 회고
외부 서비스 장애 상황에서도 로그인 서비스 중단 없이 운영 가능해졌습니다. 외부 의존성이 있는 모든 호출에 이 패턴을 일관되게 적용하는 것이 중요합니다.