목차6개 항목
출처와 참고
ByteByteGo의 System Design 101 가이드 「Polling vs Webhooks」, 「Short/long polling, SSE, WebSocket」을 바탕으로 재구성한 노트다.
무엇을 푸는가
결제 대행사, 배송 업체, Git 호스팅처럼 다른 서비스에서 일어난 일을 내 서버가 알아야 할 때가 있다. 결제가 완료됐는지, 배송이 출발했는지, 푸시가 들어왔는지. 방법은 둘이다.
폴링: 내가 계속 묻는다
sequenceDiagram participant M as 내 서버 participant E as 외부 서비스 M->>E: 새 소식 있어? E-->>M: 없음 M->>E: 새 소식 있어? E-->>M: 없음 M->>E: 새 소식 있어? E-->>M: 결제 완료!
웹훅: 일이 생기면 상대가 부른다
sequenceDiagram participant M as 내 서버 participant E as 외부 서비스 M->>E: (사전에) 이 URL로 알려 줘 E->>M: (이벤트 발생) POST /webhooks/payment
웹훅(webhook)은 역방향 API, 또는 HTTP 콜백이다. 내가 엔드포인트를 만들어 상대에게 등록해 두면, 상대가 이벤트를 HTTP 요청(보통 JSON을 담은 POST)으로 보내 준다.
비교
| 항목 | 폴링 | 웹훅 |
|---|---|---|
| 누가 먼저 말하나 | 소비자(나) | 생산자(외부 서비스) |
| 실시간성 | 폴링 간격만큼 늦다 | 이벤트 직후 도착 |
| 자원 효율 | 변화가 없어도 요청이 계속 나간다 | 일이 있을 때만 요청이 온다. 처리량이 많을수록 유리 |
| 통제권 | 언제, 얼마나 가져올지 내가 정한다 | 상대가 보내는 시점과 속도에 맞춰야 한다 |
| 인프라 요구 | 바깥으로 나가는 요청만 되면 된다 | 외부에서 들어올 수 있는 공개 엔드포인트가 필요하다 |
| 실패 양상 | 요청이 실패하면 다음 주기에 다시 묻는다 | 네트워크 문제로 알림을 놓칠 수 있다. 재시도 정책에 기대야 한다 |
고르는 기준
- 웹훅: 즉시 반응해야 하고(결제 확정 후 주문 처리), 이벤트가 많고, 공개 엔드포인트를 열 수 있을 때.
- 폴링: 방화벽·사내망 때문에 들어오는 요청을 받을 수 없을 때, 상대가 웹훅을 제공하지 않을 때, 정해진 시각에 모아서 처리하면 충분할 때.
- 둘을 함께: 웹훅으로 빠르게 받고, 놓친 이벤트를 메우기 위해 주기적인 조회(대사, reconciliation)를 덧붙이는 구성이 흔하다. 결제처럼 하나도 놓치면 안 되는 이벤트에 쓴다.
웹훅을 받는 쪽이 갖출 것
웹훅 엔드포인트는 인터넷에 열린 입구다. 아무나 그 URL로 가짜 이벤트를 보낼 수 있다는 전제로 만든다.
| 항목 | 이유와 방법 |
|---|---|
| 서명 검증 | 보내는 쪽이 공유 비밀키로 본문의 HMAC 서명을 헤더에 실어 준다. 받은 본문으로 같은 서명을 계산해 비교하고, 맞지 않으면 버린다(API 키와 HMAC 요청 서명) |
| 재전송 공격 방지 | 서명에 포함된 타임스탬프가 허용 범위를 벗어나면 거절한다 |
| 빠른 응답 | 받자마자 2xx를 돌려주고 실제 처리는 큐에 넘긴다. 응답이 늦으면 보내는 쪽이 실패로 보고 재시도한다 |
| 멱등 처리 | 재시도 때문에 같은 이벤트가 여러 번 온다. 이벤트 ID를 저장해 두고 이미 처리한 것은 건너뛴다 |
| 순서 가정 금지 | 이벤트가 발생 순서대로 오지 않을 수 있다. 이벤트의 시각이나 버전을 보고 최신 상태만 반영하거나, 필요하면 원본 API를 다시 조회한다 |
| HTTPS | 본문에 민감 정보가 실리므로 암호화된 엔드포인트만 등록한다 |
flowchart TB p["POST /webhooks/payment"] -->|"서명·타임스탬프 검증 실패"| r1["400/401, 끝"] p -->|"이벤트 ID가 이미 처리됨"| r2["200, 끝 (중복)"] p --> q["큐에 넣고 즉시 200"] q --> w["워커가 주문 상태 갱신"]
브라우저 쪽의 대응 관계
웹훅과 폴링은 주로 서버와 서버 사이의 이야기다. HTTP 서버는 브라우저에 먼저 연결을 걸 수 없으므로, 브라우저가 서버의 변화를 받을 때는 다른 도구를 쓴다.
| 누가 일하나 | 방식 | 설명 |
|---|---|---|
| 브라우저가 계속 묻는다 | 숏 폴링 | 일정 간격으로 다시 요청한다 |
| 브라우저가 묻고 서버가 붙잡는다 | 롱 폴링 | 서버가 새 데이터가 생길 때까지 응답을 미룬다 |
| 연결 후 서버가 보낸다 | SSE | 서버 → 브라우저 단방향 스트림 |
| 연결 후 양쪽이 보낸다 | WebSocket | 전이중(full-duplex) 양방향 |
브라우저 쪽 방식의 비교와 구현은 WebSocket과 브라우저 실시간 통신에 있다.
정리
- 폴링은 내가 묻고, 웹훅은 상대가 부른다.
- 웹훅은 실시간이고 효율적이지만 공개 엔드포인트와 재시도·중복 대비가 필요하다.
- 받는 쪽은 서명 검증 → 중복 확인 → 큐에 넘기고 즉시 2xx 순서로 만든다.
- 놓치면 안 되는 이벤트는 웹훅에 주기적 조회를 덧붙여 메운다.
관련 노트: API 아키텍처 스타일, WebSocket, 브라우저 실시간 통신: 롱 폴링, SSE, WebSocket 클라이언트, API 키와 HMAC 요청 서명, API 보안 체크리스트