웹 후크: 재생 및 승인
1) 기본 전달 모델
적어도 한 번 (기본값) -이벤트는 1 회 이상 전달됩니다. 정확히 한 번의 보증은 수신기 demempotency에 의해 달성됩니다.
승인 (ACK): 수신자의 2xx (보통 200/204) 만이 성공을 의미합니다. 다른 모든 것은 실패로 해석되어 반복으로 이어집니다.
빠른 ACK: 전체 비즈니스 처리 후가 아니라 이벤트를 차례로 배치 한 후 2xx에 응답하십시오.
2) 이벤트 형식 및 필수 제목
페이로드 (예)
json
{
"id": "evt_01HXYZ",
"type": "order. created",
"occurred_at": "2025-11-03T18:10:12Z",
"sequence": 128374,
"source": "orders",
"data": { "order_id": "o_123", "amount": "49. 90", "currency": "EUR" },
"schema_version": 1
}
'X-Webhook-ID: evt _ 01HXYZ' - 고유 한 이벤트 ID (중복 제거 사용).
'X-Webhook-Seq: 128374' - 모노톤 시퀀스 (구독/테마 별).
'X-Signature: sha256 =
'X- 재시도: 0,1,2... '시도 번호입니다.
'X-Webhook-Version: 1' - 계약 버전.
(선택 사항) '추적' -추적 상관 관계.
수신자의 응답
2xx-성공적으로 수락되었습니다 (이 'id' 에 대한 추가 반복은 없습니다).
410 Gone-엔드 포인트 삭제/비활성 → 발신자는 재 시도를 종료하고 구독을 비활성화합니다.
429/5xx/타임 아웃-발신자는 리트레이 정책에 따라 반복됩니다.
3) 정책 재 시도
권장 백오프 래더 (+ 지터)
'1, 3, 10, 30, 2m, 10m, 30m, 2 시간, 6 시간, 24 시간' (예: 48-72 시간).
규칙:- "무리 효과" 를 피하기위한 지수 백오프 + 랜덤 지터 (λ20-30%).
- 임시 오류에 대한 정족수 (예: 5xx 또는 네트워크 타임 아웃 경우 다시 시도).
- 존중 429: 최소 설정 '분 (재생 후 헤더, 다음 백오프 창)'.
타임 아웃 및 크기
연결 시간이 3-5 초 정도입니다. 총 응답 타임 아웃
계약에 따른 본체의 크기 (예:- 4) 이념과 중복 제거
이데올로기 적용: 동일한 'id' 의 반복 처리는 동일한 결과를 반환하고 상태를 다시 변경해서는 안됩니다.
수신자 측의 데드 업 스토리지: TTL
구성 키: 여러 주제 → '(구독 _ id, 이벤트 _ id)' 인 경우.
5) 주문 및 "정확히 한 번의 효과"
분산 시스템에서 엄격한 주문을 보장하기는 어렵습니다. 사용하기:- 키 별 파티션: 동일한 논리 세트 (예: 'order _ id') 는 항상 하나의 "채널" 로 전달됩니다.
- 시퀀스: 이전 'X-Webhook-Seq' 로 이벤트를 거부하고 누락 된 이벤트가 도착하기 전에 "주차장" 에 배치하십시오.
- 정확히 한 번의 효과는 다음을 통해 달성됩니
적용된 작업 로그 (아웃 박스/받은 편지함 패턴),
데이터베이스에서 '이벤트 _ id' 로 트랜잭션 업저트,
복잡한 프로세스에 대한 sagas/보상.
6) 상태 코드 별 오류 해결 (표)
7) 채널 보안
각 메시지의 HMAC 서명; "시간 창" (미트 및 재생 공격) 으로 수신기를 확인하십시오.
민감한 도메인에 대한 mTLS (LCC/결제).
발신 주소의 IP 허용리스트, SL 1. 2 +, HSTS.
PII 최소화: 불필요한 개인 데이터를 보내지 마십시오. 로그에서 변장.
비밀 회전: 현재 키 하나를 나타내는 두 개의 유효한 키 (활성/다음) 및 'X-Key-ID' 헤더.
8) 대기열, DLQ 및 리플레이
발신자 쪽의 출력 대기열/로그에 이벤트를 작성해야합니다 (안정적인 재생을 위해).
최대 배상금을 초과하면 이벤트는 원인과 함께 DLQ (Dead Letter Queue) 로 이동합니다.
RPS 제한 및 추가 서명/인증을 통해 'id '/시간 범위/주제별로 다시 제출하십시오.
(PHP 3 = 3.0.6, PHP 4)
POST /v1/webhooks/replay
{ "subscription_id": "sub_123", "from": "2025-11-03T00:00:00Z", "to": "2025-11-03T12:00:00Z" }
→ 202 Accepted
9) 계약 및 버전
이벤트 버전 ('스키마 _ 버전' 필드) 및 전송 ('X-Webhook-Version').
필드를 옵션으로 만 추가하십시오. 삭제시 - 사소한 마이그레이션 및 전환 기간 (이중 쓰기).
문서 이벤트 형식, 예, 스키마 (JSON Schemas), 오류 코드.
10) 관찰 및 SLO
% 1을 (를) 읽을 수 없습니다
'delivery _ success _ rate' (2xx/all 시도), 'first _ sid _ success _ rate'
'retries _ total', 'max _ rish _ age _ secons', 'dlq _ count'
(PHP 3, PHP 4)
수신자 키 지표:- (PHP 3 = 3.0.6, PHP 4)
- (PHP 3 = 3.0.6, PHP 4)
99. 이벤트의 9% 는 첫 번째 ACK 약 60 초 (28d) 를받습니다.
- DLQ 지정 0. 전체의 1%; DLQ는 24 시간 동안 재생됩니다.
11) 타이밍 및 네트워크 중단
타임 필드에서 UTC 사용; NTP를 동기화합니다.
지연을 읽으려면 'arsed _ at' 를 보내고 'salved _ at' 를 수정하십시오.
긴 휴식 시간으로 네트워크/엔드 포인트 → 가 대기열에 누적되어 성장이 제한됩니다 (역압 + 할당량).
12) 권장 한계 및 위생
구독 당 RPS (예: 50 RPS, 버스트 100) + 동시성 (예: 10).
최대. 본문: 64-256K; 자세한 내용은 "알림 + IM" 및 다운로드 서명입니다.
'뱀의 이벤트 이름. 사례 '또는' 점. (PHP 3 = 3.0.6, PHP 4) ').
수신기의 쓰기 작업의 엄격한 dempotency.
13) 예: 보내기 및 수신자
13. 1 보내기 (의사 코드)
python def send_event(event, attempt=0):
body = json. dumps(event)
sig = hmac_sha256_base64(body, secret)
headers = {
"X-Webhook-Id": event["id"],
"X-Webhook-Seq": str(event["sequence"]),
"X-Retry": str(attempt),
"X-Signature": f"sha256={sig}",
"Content-Type": "application/json"
}
res = http. post(endpoint, body, headers, timeout=10)
if 200 <= res. status < 300:
mark_delivered(event["id"])
elif res. status == 410:
deactivate_subscription()
else:
schedule_retry(event, attempt+1) # backoff + jitter, respect 429 Retry-After
13. 수신기 2 개 (의사 코드)
python
@app. post("/webhooks")
def handle():
body = request. data headers = request. headers assert verify_hmac(body, headers["X-Signature"], secret)
evt_id = headers["X-Webhook-Id"]
if dedup_store. exists(evt_id):
return, "" 204 enqueue_for_processing (body) # fast path. dedup_store put(evt_id, ttl=723600)
return, "" 202 # or 204
14) 테스트 및 혼돈 관행
부정적인 경우: 유효하지 않은 서명, 429/5xx, 타임 아웃, 410, 큰 페이로드.
행동: 고장, 중복, 1-10 분의 지연, 24 시간 동안 중단됩니다.
하중: 버스트 10 ×; 역압 및 DLQ 지속성을 확인하십시오.
계약: JSON 스키마, 필수 제목, 안정적인 이벤트 유형.
15) 구현 점검표
- 2xx = ACK, 대기열 후 빠른 반환
- 지수 백오프 + 지터, '재시도 후' 존중
- 수신기 IDempotency 및 X-Webhook-ID (TTL 느낌표)
- HMAC 서명, 비밀 회전, 선택적 mTLS
- DLQ + 재생 API, 모니터링 및 경고
- 한계: 시간 초과, RPS, 신체 크기
- 주문: 키 또는 '시퀀스' + "주차장" 별 파티션
- 문서: 스키마, 예, 오류 코드, 버전
- 혼돈 테스트: 지연, 중복, 네트워크 오류, 긴 재생
16) 미니 -FAQ
항상 200에 대답해야합니까?
2xx는 성공으로 간주됩니다. 202/204는 "대기 허용" 에 대한 일반적인 관행입니다.
재생을 중단 할 수 있습니까?
예, 410 응답 및/또는 발신자의 콘솔/API (구독 취소) 를 통한 응답.
큰 페이로드는 어떻습니까?
"알림 + 보안 맵" 을 보내고 다운로드 요청에 서명하고 TTL을 설치하십시오.
주문을 보장하는 방법?
키 + '시퀀스' 로 분할; 불일치의 경우 - "주차장" 및 재생.
합계
안정적인 웹 후크는 명확한 ACK (2xx) 의미론, 백오프 + 지터를 사용한 합리적인 반복, 엄격한 dempotence 및 중복 제거, 유능한 보안 (HMAC/mSL), 대기열 + DLQ + 재생 및 투명한 관찰 가능성입니다. 계약을 수정하고 한계와 측정 항목을 입력하고 정기적으로 혼돈 시나리오를 실행하십시오. 첫 번째 실패시 통합이 "쏟아져 나옵니다".