피드로 돌아가기
Retrying HTTP Requests in Go Without Making It Worse
Dev.toDev.to
Backend

Thundering Herd 및 Retry Storm 방지를 위한 Go 기반의 정밀한 HTTP Retry 전략 설계

Retrying HTTP Requests in Go Without Making It Worse

Krishan Kumar2026년 5월 26일7intermediate

Context

단순 반복 횟수 기반의 Naive Retry 구현 시 발생하는 Request Body 소실, Thundering Herd 현상, 불필요한 상태 코드 재요청 문제를 분석함. 특히 서버 복구 능력을 저하시키는 동기적 재시도 패턴의 구조적 한계를 해결하고자 함.

Technical Solution

  • Request Body를 메모리에 버퍼링하여 재시도 시 Body 소실을 방지하고 매 요청마다 독립적인 스트림을 제공하는 구조 설계
  • Exponential Backoff와 Full Jitter(random 0 to d)를 결합하여 클라이언트 간 요청 간격을 완전히 분산시키는 전략 채택
  • time.Sleep 대신 Interface 기반의 Mockable Sleeper를 도입하여 테스트 실행 시간을 마이크로초 단위로 단축하고 Context Cancelation 즉시 반영
  • HTTP Method별 Idempotency를 고려하여 GET/PUT 등 안전한 메서드만 기본 재시도하고 POST는 Idempotency Key 설정 시에만 허용하는 정책 적용
  • Retry-After 헤더의 Delta-seconds 및 HTTP-date 형식을 모두 처리하되 최대 대기 시간을 캡핑하여 고루틴 점유 시간 최적화
  • 전체 시스템의 연쇄적 과부하를 막기 위해 요청률의 일정 비율로 재시도 횟수를 제한하는 Retry Budget 개념 도입

- POST 요청 재시도 전 Idempotency Key 도입 여부 확인 - 단순 고정 대기 시간이 아닌 Exponential Backoff + Full Jitter 적용 여부 검토 - 전체 타임아웃(Context Deadline)과 개별 시도 타임아웃(Client Timeout)을 분리하여 설정 - 서비스 체인 구조에서 Retry Storm 방지를 위한 Retry Budget 설정 검토

원문 읽기