멱등성(idempotency)은 같은 연산을 한 번 하든 여러 번 하든 결과가 같다는 성질이다. 네트워크는 실패하고 메시지는 중복되므로, 재시도가 안전하려면 받는 쪽이 멱등해야 한다.
HTTP 메서드
- GET, PUT, DELETE는 명세상 멱등이다. 같은 PUT을 두 번 보내도 리소스는 같은 상태가 된다
- POST는 멱등이 아니다. 결제 요청을 두 번 보내면 두 번 결제될 수 있다
- 그래서 결제 같은 POST에는 클라이언트가 만든 멱등 키(Idempotency-Key)를 헤더로 보내게 하고, 서버는 같은 키의 두 번째 요청에 첫 결과를 그대로 돌려준다
메시지 소비자
Kafka 같은 브로커와 아웃박스 워커는 보통 at-least-once(최소 한 번 전달)로 전달한다. "최소 한 번"이라 같은 이벤트가 두 번 올 수 있다.
- 같은 ID로 덮어쓰기: 검색 색인이나 캐시에 문서 ID 기준으로 upsert하면 중복이 와도 결과가 같다
- 처리한 이벤트 ID 기록: 처리 테이블에 이벤트 ID를 유니크 키로 남기고, 이미 있으면 건너뛴다
- 버전 비교: 이벤트에 버전·타임스탬프를 담아 현재보다 오래된 변경은 무시한다. 순서 꼬임도 함께 막는다
INSERT INTO processed_events (event_id) VALUES ($1)
ON CONFLICT (event_id) DO NOTHING; -- 영향받은 행이 0이면 이미 처리됨혼동 주의
멱등은 "부수 효과(side effect)가 없다"와 다르다. DELETE는 상태를 바꾸지만 여러 번 해도 결과가 같아 멱등이다. 응답 코드는 달라질 수 있다(첫 번째 204, 두 번째 404).
이벤트가 늦게·중복으로 도착하는 세계에서 결국 같은 상태로 모이게 하는 장치라 최종 일관성과 짝을 이룬다. 요청 횟수 자체를 제한하는 것은 요청 제한 (Throttling), 재사용 가능한 순수 함수의 성질은 명령-질의 분리과도 이어진다.
출처: RFC 9110: Idempotent Methods · IETF 초안: The Idempotency-Key HTTP Header Field · microservices.io: Idempotent Consumer