단순 이벤트 구독 코드가 프로덕션에서 실패하는 이유
WebSocket으로 블록체인 이벤트를 구독하는 코드를 처음 작성하면 “동작은 한다”는 느낌을 받는다. 특정 컨트랙트의 이벤트를 실시간으로 받아서 데이터베이스에 저장하고 알림을 발송한다. 로컬 테스트도 통과한다.
그런데 이 코드를 실제 서비스에 배포하면 언젠가 반드시 실패한다. 단순 구독 코드에는 네 가지 핵심 기능이 없기 때문이다. 이 글에서는 그 4대 위험을 구체적인 시나리오로 이해하고, 왜 각각이 치명적인지를 살펴본다.
위험 1: WebSocket 연결 끊김
WebSocket 연결은 예상보다 자주 끊긴다. 네트워크 불안정, RPC 노드 재시작, 서버 메모리 부족 등 다양한 원인이 있다. 연결이 끊기는 순간부터 재연결 완료까지의 시간 동안 발생한 이벤트는 실시간 구독으로는 받을 수 없다.
이 “블라인드 구간”을 처리하는 로직이 없으면 데이터 누락이 발생한다.
비유: 뉴스 프로그램 생방송을 보다가 채널이 끊겼다. 다시 연결하면 지금 방송은 볼 수 있지만, 끊겨 있는 동안 방영된 뉴스는 볼 수 없다. 녹화 기능(과거 이벤트 보완)이 있어야 한다.
위험 2: 서버 재시작
배포, 업데이트, 장애 복구 등으로 서버는 반드시 재시작된다. 마지막으로 처리한 이벤트의 블록 번호를 어딘가에 저장해두지 않으면, 재시작 후 어디서부터 다시 시작해야 하는지 알 수 없다.
- 처음부터 시작하면: 이미 처리한 이벤트를 또 처리한다 (중복)
- 현재 블록부터 시작하면: 재시작 전 미처리 이벤트가 누락된다
두 선택지 모두 문제다. 이를 해결하려면 “커서(Cursor) 관리”가 필요하다.
위험 3: Reorg (블록체인 재조직)
블록체인에서 블록이 체인에 포함됐다가 더 긴 체인이 나타나면 기존 블록이 제거된다. 이미 “처리 완료”로 기록한 이벤트가 Reorg로 무효화될 수 있다. 단순 구독 코드는 이 상황을 감지하지 못하고 처리 완료 상태를 유지한다.
비유: 계좌에 입금이 됐다고 문자를 받았다. 입금 처리를 완료했는데, 나중에 은행에서 “그 입금이 취소됐다”고 연락이 온다. 취소를 감지하고 역방향 처리를 하지 않으면 장부가 맞지 않는다.
실제 사고 사례가 있다. NFT 마켓플레이스에서 구매 완료 이벤트를 받자마자 NFT를 해제했다. 해당 블록이 Reorg되어 구매 트랜잭션이 무효화됐지만 NFT는 이미 해제된 상태였다.
위험 4: 중복 이벤트
같은 이벤트를 두 번 받는 상황이 있다:
- 실시간 구독과 과거 이벤트 조회가 겹치는 구간
- Reorg 후 같은 트랜잭션이 다른 블록에 다시 포함될 때
- 재연결 후 중복 구독 설정
중복으로 같은 입금을 두 번 처리하거나 같은 알림을 두 번 발송하면 심각한 운영 문제가 된다.
실제 사고: 한 거래소에서 WebSocket 이벤트 구독 서버가 약 3시간 동안 연결 끊김을 감지하지 못했다. 그 사이 수백 건의 입금 이벤트가 누락됐다. 관련 사용자들의 계정에 입금이 반영되지 않았고, 고객 지원 요청이 폭증했다.
WebSocket vs HTTP Polling: 두 방식의 장단점
WebSocket 구독 방식
장점: 이벤트 발생 즉시 알림. 지연이 낮다.
단점: 연결이 끊기면 이벤트를 놓친다. 재연결 로직이 복잡하다.
HTTP Polling 방식
장점: 안정적이다. 매번 새로운 HTTP 요청이므로 연결 관리가 없다.
단점: 요청 주기마다 지연이 생긴다. RPC 노드에 부하가 생긴다.
두 방식의 장점을 결합하는 패턴이 있다: “WebSocket = 신호, HTTP = 데이터”
- WebSocket으로 “새 블록이 생겼다”는 신호만 받는다
- 신호를 받으면 HTTP getLogs로 해당 블록의 이벤트를 조회한다
이 패턴은 WebSocket이 끊겨도 다음 연결 시 놓친 블록을 HTTP로 보완할 수 있다. 가장 실용적인 블록체인 이벤트 수신 패턴이다.
금융기관이 자체 RPC 노드가 필요한 이유
일반 개발자는 Infura, Alchemy 같은 외부 RPC 서비스를 쓴다. 하지만 교보생명, 증권사, 은행 같은 금융기관은 외부 RPC를 그냥 쓸 수 없다. 이유는 세 가지다.
- 데이터 외부 유출: 모든 트랜잭션 데이터가 외부 업체 서버를 통해 나간다. 금융 규제상 외부에 노출되면 안 되는 정보들이다.
- 단일 장애점: 외부 RPC 서비스가 장애 나면 서비스 전체가 중단된다. 2022년 Alchemy, Infura 장애 때 수십 개의 DeFi 서비스가 동시에 중단됐다.
- 규제 감사: 금융당국 감사 시 “트랜잭션 처리를 외부 업체에 맡겼다”는 것은 내부통제 관점에서 리스크로 분류된다.
해결 방법은 DMZ Zone에 Private RPC Node를 배치하는 것이다. 내부망과 인터넷 사이에 완충 구간을 두는 방식이다. 내부 시스템은 DMZ의 Private RPC만 바라보고, DMZ 노드가 퍼블릭 체인과 직접 피어링(P2P 동기화)한다.
핵심 요약
- WebSocket 연결 끊김, 서버 재시작, Reorg, 중복 이벤트는 프로덕션 이벤트 파이프라인의 4대 위험이다
- 단순 구독 코드는 이 네 가지를 하나도 처리하지 못한다
- “WebSocket = 신호, HTTP = 데이터” 패턴이 안정적인 기반이다
- Finalized 상태 전의 이벤트를 처리할 때는 나중에 무효화될 수 있다는 것을 항상 고려해야 한다
- 금융기관 수준의 서비스는 DMZ Zone Private RPC 노드가 필수다
다음 글에서는 이 4대 위험을 해결하는 구체적인 방법 — 커서 관리, 멱등성 설계, 상태 머신 — 을 다룬다.