← 기술 지식

기술 지식 / 컴퓨터 과학 / 네트워크 / HTTP

HTTP 메서드 의미와 실패 후 재시도

safe·idempotent·캐시·기밀성을 분리하고 429·503·504와 멱등 요청 키·기한·시도 예산의 관계를 설명합니다.

네트워크 · 원리·구현·운영
기술 지식 트리

HTTP 재시도는 상태 코드 숫자를 보고 요청을 반복하는 기능이 아니라, 원본이 실행됐을 가능성과 같은 논리 작업을 다시 보내도 효과가 한 번만 남는지를 판단하는 계약입니다. 메서드의 safe·idempotent 의미, 서버의 멱등 키, 전체 deadline과 하위 호출 예산을 한 경로에서 함께 결정해야 합니다.

GET 안전성과 관찰적 부수 효과의 구분

상품 조회 GET이 접근 로그와 통계 카운터를 남겨도, 클라이언트가 요청한 의미가 조회라면 안전한 메서드의 취지와 충돌하지 않습니다. 그러나 GET 링크에 보상 지급·삭제를 넣으면 크롤러·미리 가져오기·링크 검사·새로고침이 의도하지 않은 변경을 만들 수 있습니다.

안전성은 클라이언트가 요청한 의미가 상태 변경을 요구하는지이고, 멱등성은 동일 요청을 반복한 의도된 최종 효과가 한 번과 같은지입니다. DELETE는 두 번째 응답이 404로 달라도 의도된 삭제 효과가 같을 수 있습니다. 응답 문자열의 동일성과 멱등성은 다릅니다.

메서드·캐시·기밀성의 분리

선택 말해 주는 것 말해 주지 않는 것
GET 표현 조회의 안전·멱등 의미 항상 공개 캐시 허용
POST 대상이 본문을 처리하는 요청 기본적으로 중복 방지·기밀성
HTTPS 전송 구간 보호 서버 로그·브라우저 저장 보호
Cache-Control 저장·재사용 정책 현재 사용자 인가

민감값을 POST 본문에 넣으면 URL 기록보다 노출 경로를 줄일 수 있지만 암호화되는 것은 아닙니다. 로그·trace·오류 보고·개발자 도구에서 본문이 남을 수 있습니다. TLS·마스킹·저장 제한·권한을 함께 적용합니다.

POST 응답도 명시적인 HTTP 캐시 조건에서 재사용 가능할 수 있지만 일반 캐시의 지원은 확인해야 합니다. GET이라고 무조건 캐시되고 POST라고 절대 캐시되지 않는다는 규칙으로 설계하지 않습니다.

상태 코드와 실행 결과 불확정성

결과 알려 주는 신호 주의할 불확정성
429 요청 제한 즉시 반복하면 제한·부하 증폭
503 일시 서비스 불가 가능성 모든 구현에서 미실행을 보장하지 않음
504 gateway가 제때 응답 못 받음 원본은 이미 커밋했을 수 있음
연결 오류 응답을 못 얻음 전송 전 실패인지 응답 유실인지 구분 필요

주문 요청이 gateway에서 504를 받았다고 하겠습니다. gateway가 응답을 못 받은 것뿐이라 원본이 아직 실행되지 않았는지, 이미 커밋하고 응답만 잃었는지는 이 상태 코드만으로 알 수 없습니다. 상태 trace를 client sends key=K → origin commits order → gateway returns 504 → client retries key=K로 적으면, 재시도 전 먼저 해야 할 일이 새 주문 생성이 아니라 K의 결과 조회임을 알 수 있습니다. 결과가 아직 확정되지 않았고 서버 계약이 안전한 반복을 보장할 때만 같은 K로 다시 보내며, 새 K를 만들면 동일 사용자의 한 주문이 두 논리 작업으로 갈라집니다.

오류 뒤에는 안전성과 예산을 먼저 확인합니다응답 실패·timeout. 효과와 요청 계약 확인: 멱등 메서드 · 요청 키, 불확정 결과 조회. 기한·시도·부하 예산. 제한된 재시도 또는 종료실행 가능성 판단안전하게 재실행 가능남은 시간 내 선택응답 실패·timeout효과와 요청 계약 확인멱등 메서드 · 요청 키불확정 결과 조회기한·시도·부하 예산제한된 재시도 또는 종료
오류 뒤에는 안전성과 예산을 먼저 확인합니다 화살표는 재시도 판단 순서입니다. 코드만 보고 즉시 재전송하지 않고 실제 효과의 불확정성과 같은 논리 요청의 식별을 유지합니다.
그림을 글로 읽기
  • 응답 실패·timeout
  • 효과와 요청 계약 확인: 멱등 메서드 · 요청 키 · 불확정 결과 조회
  • 기한·시도·부하 예산
  • 제한된 재시도 또는 종료
  1. 응답 실패·timeout → 효과와 요청 계약 확인: 실행 가능성 판단
  2. 효과와 요청 계약 확인 → 기한·시도·부하 예산: 안전하게 재실행 가능
  3. 기한·시도·부하 예산 → 제한된 재시도 또는 종료: 남은 시간 내 선택

동일 주문의 동일 논리 키

POST 주문 생성에 멱등성 키를 제공한다면 사용자·작업 범위·본문 fingerprint를 함께 기록해야 합니다. 새 네트워크 시도마다 새 키를 만들면 같은 주문이 다른 요청처럼 실행됩니다. 반대로 본문이 같은 별도 정상 주문을 같은 키로 합치면 주문을 잃습니다.

키 기록과 실제 변경은 같은 원자 경계에 있어야 하고, 같은 키에 다른 인자는 거절합니다. 기록이 만료된 뒤 늦은 재시도가 오면 중복 방지가 사라질 수 있으므로 보관 기간과 오래된 요청 거절·원장 조회 정책을 정합니다. 메서드를 POST로 정했다는 사실만으로 이 계약이 생기지는 않습니다.

Retry-After와 전체 기한의 결합

Retry-After는 지연 시간 또는 HTTP 날짜로 주어질 수 있습니다. 날짜 형태는 시계 차이와 파싱 실패를 고려해야 합니다. 지시된 대기가 사용자의 남은 기한을 넘으면 무한히 기다리기보다 미완료·재시도 가능 상태를 명시합니다.

onRetryableFailure(request, attempt, deadline):
    require request.has_safe_repeat_contract
    delay = combine_retry_after_and_bounded_backoff_with_jitter()
    if attempt >= MAX_ATTEMPTS or now()+delay+nextAttemptBudget > deadline:
        return final_failure_or_uncertain_status
    wait(delay)
    return resend_same_logical_request()

상위 3회·하위 3회 재시도가 겹치면 최대 9회 호출이 될 수 있습니다. 원본 사용자 요청 ID와 시도 ID를 구분하고 전체 예산을 조정합니다. 거절률과 최종 성공률뿐 아니라 실제 하위 호출량·회복 시간을 함께 봐야 합니다.

실패 후 상태 보존 검증

응답만 유실된 주문, 적용 전 명시 거절, gateway timeout, Retry-After가 기한보다 긴 경우를 분리합니다. 반복 GET에는 의도한 지급·삭제가 없고, POST 재전송에는 같은 요청 키의 효과가 한 번만 남아야 합니다.

로그·미리보기·캐시 재검증이 어떤 메서드를 호출하는지도 확인합니다. 재현 연습에서는 응답 유실, 명시적 4xx 거절, 429의 긴 Retry-After, 503/504 뒤 이미 커밋된 경우를 분리합니다. 예상 결과는 safe한 조회는 반복해도 업무 변경이 없고, 주문 POST는 동일 키의 결과가 한 건으로 수렴하며, deadline을 넘는 경우 성공을 추측하지 않고 미확정 상태를 반환하는 것입니다.

후속·관련 개념

함께 읽을 문서

전체 기술 지식
선택 연습 · 관련 질문 4개

질문은 이해를 확인하는 보조 자료입니다. 학습 경로와 문서의 범위는 질문 수와 독립적입니다.