🛒 Backend Engineering · 6/9 · 약 8분
외부 결제 알림은 한 번만, 발생 순서대로 도착하지 않는다. 응답이 늦으면 같은 사건이 다시 오고 네트워크 지연이 생기면 나중 사건이 먼저 도착할 수 있다.
가상의 주문 서비스에서 이 조건을 정상 입력으로 두고 수신 흐름을 다시 검토했다. 알림 수신과 주문 상태 변경을 분리하자 검증, 중복 제거, 순서 판단, 재처리의 책임이 각각 보이기 시작했다.
#Backend · #Webhook · #Idempotency · #EventDriven
외부 시스템은 수신 성공을 확인하지 못하면 같은 알림을 다시 보낼 수 있다. 내부 처리는 끝났지만 응답만 사라진 경우에도 재전송이 발생한다. 따라서 동일 사건의 반복은 전달 실패가 아니라 적어도 한 번 전달 방식에서 자연스러운 입력이다.
서로 다른 사건의 도착 순서도 발생 순서와 같다고 보장할 수 없다. 처리 완료 사건 뒤에 이전 단계 사건이 늦게 도착할 수 있고, 여러 작업자가 병렬로 사건을 소비하면 처리 완료 순서도 달라진다. 웹훅 처리기는 ‘새 요청’이 아니라 ‘검증과 판정이 필요한 사건’으로 입력을 바라봐야 한다.
지켜야 할 불변식은 두 가지다. 같은 외부 사건은 내부 부수 효과를 한 번만 만든다. 그리고 늦은 사건은 이미 확정된 상태를 이전 단계로 되돌리지 않는다.
첫 경계는 발신 신뢰성이다. 외부 제공자가 정의한 검증 방식과 허용 시간을 적용하고 검증에 필요한 원문이 중간 변환으로 바뀌지 않게 한다. 검증에 실패한 알림은 업무 상태를 바꾸지 않고 거절하거나 별도 확인 대상으로 남긴다.
검증을 통과한 사건은 외부 사건 식별자, 수신 시점, 처리 상태를 함께 보관한다. 사건 식별자에 유일성 제약을 두면 같은 알림이 반복되어도 새 작업 대신 기존 결과를 찾을 수 있다. 이 기록은 중복 제거 장치인 동시에 지연과 실패를 조사하는 증거가 된다.
처리 순서는 다음처럼 분리할 수 있다.
외부 알림 수신
↓
발신 검증 ── 실패 → 거절 또는 격리
↓
사건 기록 ── 중복 → 기존 처리 결과 반환
↓
현재 상태와 전이 규칙 확인
↓
허용된 변화와 부수 효과 반영
사건 기록과 업무 변경을 한 저장 경계에서 묶을 수 없다면, 처리 예정 상태와 재실행 가능한 작업을 남겨 중간 실패를 복구해야 한다.