API Timeout 설정 (무한대기, 재시도, 환경별조정)
API Timeout 값을 짧게 잡으면 시스템이 안정될까요, 아니면 오히려 정상 요청마저 끊어버리는 독이 될까요? 실제로 결제 API를 연동하면서 이 질문에 대한 답을 뼈저리게 배웠습니다. 처음엔 빠른 실패 처리를 위해 Timeout을 짧게 잡았다가 멀쩡한 거래가 실패하는 걸 보고 설정을 전면 재검토했거든요. 지금부터 Timeout 전략이 시스템 안정성과 사용자 경험 사이에서 어떤 균형을 찾아야 하는지, 제 경험을 바탕으로 풀어보겠습니다.
무한대기 방지와 자원 보호의 필요성
API를 호출했는데 응답이 오지 않는 상황을 상상해보세요. 요청은 계속 대기 상태에 머물고, 그 사이 서버 자원은 점유된 채로 묶여 있습니다. 이런 요청이 쌓이면 결국 시스템 전체가 마비될 수 있습니다. Timeout 설정은 바로 이 지점에서 중요한 역할을 합니다. 일정 시간 동안 응답이 없으면 요청을 강제로 종료함으로써 자원 낭비를 막는 것이죠.
특히 외부 서비스와 연동하는 환경에서는 상대방 서버 상태를 제어할 수 없기 때문에 Timeout 설정이 더욱 중요합니다. 결제 게이트웨이, 물류 조회, 인증 서비스 같은 외부 API는 언제든 지연되거나 장애가 발생할 수 있거든요. 제가 경험한 프로젝트에서도 외부 결제 API가 갑자기 느려지면서 우리 서버의 커넥션 풀(Connection Pool)이 모두 소진되는 사고가 있었습니다. 그때 Timeout을 적절히 설정했더라면 피해를 최소화할 수 있었을 거라는 생각이 듭니다.
Timeout은 단순히 응답 대기 시간만 제한하는 게 아닙니다. 장애 상황에서 시스템이 스스로를 보호할 수 있는 최소한의 방어 장치라고 볼 수 있습니다. 문제가 생긴 서비스에 요청을 계속 보내봤자 자원만 낭비되니까요. 빠르게 실패를 감지하고 대응하는 것이 전체 시스템의 가용성을 유지하는 핵심입니다.
재시도 전략과 환경별 Timeout 조정
그런데 Timeout 값을 무조건 짧게 잡는다고 능사가 아닙니다. 저는 초기에 3초로 설정했다가 네트워크 지연이 조금만 생겨도 정상 요청이 실패 처리되는 걸 보고 당황했습니다. 특히 결제 같은 중요한 트랜잭션에서 이런 실패가 발생하면 사용자는 "결제가 안 됐나?" 싶어서 다시 시도하고, 그 과정에서 중복 결제가 발생할 위험도 있습니다. 고객센터에 문의가 몇 건 들어온 뒤에야 Timeout 값을 상향 조정했습니다.
API 유형에 따라 서로 다른 Timeout 값을 적용하는 것도 중요한 전략입니다. 다음과 같은 구분이 효과적이었습니다.
- 중요도가 높은 결제·인증 API는 10~15초 정도로 여유 있게 설정했습니다. 일시적인 네트워크 지연을 감안한 것이죠.
- 조회성 API(상품 목록, 배송 조회 등)는 5~7초로 설정했습니다. 실패해도 재시도가 쉽고 사용자 영향이 상대적으로 적기 때문입니다.
- 실시간성이 중요한 모니터링 API는 2~3초로 짧게 설정했습니다. 빠른 실패 감지가 더 중요한 케이스니까요.
재시도 전략(Retry)을 함께 적용하면 Timeout으로 인한 일시적 실패를 보완할 수 있습니다. 저는 Exponential Backoff 방식을 사용했는데, 첫 번째 실패 후 1초 대기, 두 번째는 2초, 세 번째는 4초 이런 식으로 재시도 간격을 늘려가는 방식입니다. 이렇게 하니 일시적인 네트워크 불안정이나 서버 부하 상황에서도 최종적으로 성공하는 비율이 눈에 띄게 올라갔습니다.
Timeout과 재시도를 별개로 보는 게 아니라 하나의 세트로 봐야 한다고 생각합니다. Timeout만 설정하고 재시도 없이 바로 실패 처리하면 사용자 경험이 나빠지고, 반대로 재시도만 계속하고 Timeout을 길게 잡으면 장애 상황에서 복구가 늦어집니다. 둘의 균형이 중요합니다.
환경별 조정과 모니터링의 중요성
네트워크 환경은 프로젝트마다 천차만별입니다. 사내 인프라에서 API를 호출하는 경우와 클라우드 간 통신, 모바일 환경에서의 호출은 각각 지연 시간(Latency)이 완전히 다릅니다. 개발 환경에서 테스트할 때는 문제가 없었는데, 실제 운영 환경에 배포한 뒤 Timeout 에러가 빈번하게 발생하는 걸 경험했습니다. 알고 보니 개발 서버와 운영 서버의 네트워크 구성이 달라서 RTT(Round-Trip Time)가 두 배 가까이 차이 났더라고요.
그래서 이후부터 환경별로 Timeout 값을 다르게 설정하는 방식을 채택했습니다. 로컬 개발 환경에서는 3초, 스테이징은 5초, 운영은 7초 이런 식으로요. 또 API 호출 로그를 수집해서 평균 응답 시간과 P95, P99 같은 백분위수(Percentile) 지표를 모니터링했습니다. 이 데이터를 바탕으로 Timeout 값을 주기적으로 재조정하니 실패율이 크게 줄었습니다.
고정된 Timeout 값보다는 동적으로 조정하는 방식이 훨씬 효과적이었습니다. 예를 들어 Circuit Breaker 패턴과 결합하면 장애가 감지됐을 때 자동으로 Timeout을 짧게 조정하고, 정상화되면 다시 원래 값으로 복구하는 식으로 운영할 수 있습니다. 이런 방식은 Netflix의 Hystrix 같은 라이브러리에서 이미 검증된 접근법이기도 합니다(출처: Netflix Hystrix GitHub).
모니터링 없이 Timeout을 설정하는 건 눈감고 운전하는 것과 비슷합니다. 실시간으로 API 응답 시간을 추적하고, 이상 징후가 보이면 즉시 알림을 받을 수 있는 체계를 갖춰야 합니다. 저는 Grafana와 Prometheus를 활용해서 API별 응답 시간, Timeout 발생 횟수, 재시도 성공률 등을 대시보드로 관리했습니다. 이렇게 하니 문제가 생겼을 때 원인을 빠르게 파악하고 대응할 수 있었습니다.
결국 API Timeout 전략은 시스템 안정성과 사용자 경험 사이의 줄타기입니다. 너무 짧으면 멀쩡한 요청도 끊기고, 너무 길면 장애 대응이 늦어집니다. 가장 중요한 건 API 유형별로 차별화된 Timeout을 설정하고, 재시도 전략과 모니터링을 함께 운영하는 것입니다. 그리고 한 번 설정하고 끝이 아니라 운영 데이터를 기반으로 지속적으로 개선해야 합니다. Timeout은 단순한 설정 값이 아니라 서비스 품질을 좌우하는 핵심 설계 요소니까요.
댓글
댓글 쓰기