LabHub
学习 学习路径 课程

멱등성 — 두 번 눌러도 한 번만 결제되게 · 멱등 요청에도 재시도 예산이 필요하다 · 讲解

멱등 요청에도 재시도 예산이 필요하다의 설계 원리

在 LabHub 中继续学习

한 줄 요약

재시도는 ‘한 번 더’가 아니라 안전한 요청을 남은 시간과 횟수 안에서 다시 보내는 정책이다.

流程图: 한 줄 요약 · 왜 이게 필요했나 · 어떻게 동작하나 · 현장에서 만나는 모습

왜 이게 필요했나

느린 서비스에 클라이언트가 한꺼번에 재시도하면 이미 밀린 큐에 요청이 더 쌓인다.
매 요청의 timeout을 5초로 두고 3회 시도하면 전체 작업은 5초 안에 끝나지 않는다.
처음에 마감 시각을 계산하고 각 호출과 대기 전에 남은 시간을 다시 구해야 한다.
멱등 키가 있어도 비용·부하·사용자 대기 시간까지 사라지지는 않는다.

어떻게 동작하나

send(남은 시간) → 응답 → 재시도할 상태인가? → 재생해도 안전한가?                                                ↓종료 ← 횟수 또는 전체 예산 소진 ← 지터 + Retry-After 대기 계산                                                ↓                                            sleep → 다음 호출

이 실습의 정책은 429·502·503·504만 재시도한다. GET·HEAD·PUT·DELETE는 이 API의
멱등 계약을 전제로 허용하고 POST는 공백이 아닌 키가 있을 때만 허용한다. 서버가 그 키를
실제로 원자적으로 처리하지 않는다면 클라이언트에 문자열을 붙이는 것만으로는 안전하지 않다.
이전 멱등성 실습이 바로 그 서버 쪽 전제를 다룬다.

현장에서 만나는 모습

지수 백오프에 지터를 주면 모든 클라이언트가 같은 시각에 깨는 현상을 줄인다.
서버의 Retry-After가 로컬 대기보다 길면 더 긴 값을 따른다. 전체 예산보다 긴 서버
대기를 임의로 줄여 일찍 재시도하지 않고 현재 응답을 반환한다. 여기서는 정수 초 형식만
지원하며 HTTP 날짜 형식은 지원하지 않는다는 제한을 명시한다.

다음 실습에서 할 것

가짜 단조 시계·sleep·send로 실제 대기 없이 8단계를 검증한다. send는 받은 남은 시간
이내에 응답하는 어댑터라는 전제다. 동기 함수가 영원히 블록되면 실행기가 강제로 중단할
수 없으므로 실제 HTTP 어댑터에는 별도 timeout 설정이 필요하다. 예산과 최대 횟수는
최초 시도를 포함한다. 모든 상태를 재시도하거나 412 충돌을 네트워크 장애로 취급하지 않는다.

참고: [HTTP 멱등 메서드](https://www.rfc-editor.org/rfc/rfc9110.html#name-idempotent-methods)