나는 많은 API/웹훅 통합을 배포합니다. 여기 프로덕션에서 고통을 줄이는 방법 🔥
Source: Dev.to
나는 많은 API/웹훅 통합 작업을 한다. 여기서는 프로덕션에서 문제 없이 동작하게 만드는 방법을 소개한다 🔥
프리랜서 백엔드 작업을 오래 하면 다음과 같은 패턴을 발견한다:
- 클라이언트는 “아름다운 코드”에 돈을 쓰지 않는다.
- 그들은 내일 작동하는 것에 돈을 낸다.
웹훅 통합은 무작위 혼란을 가장 빠르게 만들 수 있다:
- 중복 이벤트
- 순서가 뒤바뀐 전달
- 당신을 DDoS 하는 재시도
- 고전적인 “어제는 작동했었는데 🤡”
아래는 실용적인 체크리스트 + 스케일 가능한 간단한 아키텍처다. 이론이 아니라 실제 프로덕션에서 통하는 내용이다.
1️⃣ 웹훅이 중복될 것이라고 가정합니다. 왜냐하면 그럴 것이기 때문입니다. ✅
규칙: every webhook must be idempotent.
방법:
payload에서event_id를 추출하거나(안정적인 필드에서 해시를 생성).- 상태와 함께 저장합니다.
- 중복 시
200 OK를 반환하고 아무 작업도 하지 않습니다.
500을 반환하면 재시도가 더 많이 발생합니다.
2️⃣ 빠르게 응답하고, 비동기로 처리합니다. ⚡
HTTP 요청 안에서 실제 작업을 수행하는 웹훅 핸들러는 함정입니다.
내 기본 흐름:
- 웹훅 수신.
- 서명 검증 및 기본 체크 수행.
- 원시 페이로드와 메타데이터를 DB에 저장.
200 OK를 즉시 반환.- 워커/작업 큐에서 이벤트를 처리.
이렇게 하면 DB가 느리거나 제공자가 타임아웃이 발생해도 시스템이 안정적으로 유지됩니다.
3️⃣ 원시 페이로드 저장하기. 미래의 당신이 고마워할 거예요 🧠
무언가가 깨지면 클라이언트가 이렇게 말합니다: “잘 모르겠어요, 그냥 전송되지 않았어요.”
원시 페이로드를 저장하지 않으면 증거도 없고 재생도 할 수 없습니다.
저장할 내용:
- 전체 원시 JSON 페이로드
- 관련 헤더
- 제공자 이름
- 수신 타임스탬프
- 처리 상태
- 오류 메시지(실패한 경우)
이 데이터를 가지고 할 수 있는 일:
- 이벤트 재생
- 엣지 케이스 디버깅
- 발생한 일 입증
“추측”을 “알아냄”으로 바꿔줍니다.
4️⃣ 보안: 서명을 검증하거나 보안이라고 가장하지 마세요 🔒
제공자가 서명을 지원한다면, 즽시 검증하세요—나중이나 MVP 이후가 아니라.
그렇지 않으면 스팸이나 그보다 더 심각한 악용이 가능한 공개 엔드포인트를 노출하게 됩니다.
5️⃣ 속도 제한 및 백오프: 재시도가 적이 아니라 구현이 적입니다 😅
처리 실패 시 즉시 재시도를 피하세요. 지수 백오프를 사용합니다, 예시:
- 1 분
- 5 분
- 30 분
- 2 시간
- 데드레터 큐(수동 검토)
대부분의 통합 실패는 일시적입니다(제공자 다운타임, DB 오류, 네트워크 결함). 백오프는 시스템을 탱크처럼 살아남게 합니다.
6️⃣ 실제 도움이 되는 로깅, “뭔가를 로그했다”가 아니라 📝
두 계층에서 로그를 남깁니다:
Request layer
- request ID
- provider
- event ID
- status returned
Job (worker) layer
- event ID
- job attempt number
- result
- full error stack (if any)
Extra rule: 작업이 실패하면, 이벤트 레코드 근처에 짧은 인간이 읽을 수 있는 오류를 저장합니다. 이렇게 하면 나중에 DB를 스캔할 때 즉시 패턴을 파악할 수 있습니다.
7️⃣ 최소한의 확장 가능한 구조 (단순하지만 강력함)
webhook_controller → accepts HTTP, validates, stores event, returns fast
event_store → saves raw payloads, dedup keys, statuses
processor → business logic (“what do we do with this event?”)
adapters → provider‑specific mapping (CRM A vs CRM B)
queue / worker → runs processing asynchronously with retry rules
새로운 통합을 추가하는 것은 새로운 어댑터를 만드는 것뿐이며, 나머지는 그대로 유지됩니다.
일반적인 프로덕션 “함정” (불편하게 배운 교훈) 🤝
Out‑of‑order events
“created” 이벤트보다 먼저 “updated” 이벤트를 받을 수 있습니다.
Solution: upsert를 허용하고, 이벤트 히스토리를 저장하며, 현재 상태를 기준으로 처리합니다.
Provider sends partial data
때때로 ID만 전송되고 전체 세부 정보를 가져와야 합니다.
Solution: 워커에 “hydration step”(API pull)을 추가하고 필요하면 캐시합니다.
Webhook timeouts
요청 내부에서 처리하면 타임아웃이 발생합니다.
Solution: 빠른 ACK, async processing (as described above).
TL;DR 🧾
프로덕션에서 살아남는 웹훅 통합을 만들려면:
- 멱등성(Idempotency) 은 필수입니다.
- 빠르게 응답하고, 비동기적으로 처리합니다.
- 원시 페이로드를 저장 하여 재생 및 디버깅에 활용합니다.
- 서명을 즉시 검증 합니다.
- 합리적인 재시도/백오프 전략을 구현합니다.
- 충분한 컨텍스트와 함께 로그 를 남겨 나중에 디버깅할 수 있게 합니다.
프로덕션에 웹훅을 배포해 본 적이 있다면 이미 알겠지만, 절대 “완료”가 아니라 “실제 트래픽을 견딜 만큼 안정적”이라는 점을 기억하세요 😄
아래에 가장 끔찍했던 웹훅 실화담을 남겨 주세요 👇