이벤트 필드 하나 바꿨더니 소비자가 조용히 죽었어요
발행 로그는 전부 성공인데 소비자가 멈춰 있던 이유와, payload 스키마를 바꾸기 전에 확인해야 할 인벤토리 절차를 정리했어요.
발행 로그만 보면 완벽했어요. 전부 200, 전부 success. 그런데 실제로는 아무 일도 일어나지 않았습니다.
발단은 필드 이름 하나
이벤트 payload에서 member_status 를 status 로 줄였어요. 발행하는 쪽 코드는 깔끔해졌고, 테스트도 통과했고, 발행 로그에도 문제가 없었습니다.
문제는 그 이벤트를 읽는 쪽이었어요. 소비자는 member_status 를 찾다가 undefined 를 받고, 조건문에서 아무 분기에도 걸리지 않고, 예외도 없이 그냥 끝났습니다. 에러를 던지지 않으니 재시도도 안 걸리고, 모니터링에도 안 잡혔어요. 직접 소비자 로그를 열어 보고 나서야 "받긴 받았는데 아무것도 안 했다"는 걸 알았습니다.
발행 성공은 흐름 성공이 아니에요
여기가 핵심이에요. 발행 로그의 success는 "메시지를 큐에 넣었다"는 뜻이지, "누군가 제대로 처리했다"는 뜻이 아닙니다. 이 둘을 같은 걸로 착각하면 대시보드는 초록색인데 사용자 화면은 멈춰 있는 상태가 됩니다.
특히 위험한 조합이 세 가지 있어요.
- 필드명 변경
- status 값 추가
- optional 필드의 필수화
세 경우 모두 소비자가 예외를 안 던지고 조용히 빠져나갈 수 있습니다. 타입 검증이 없는 JSON 경계라면 더 그렇고요.
바꾸기 전에 인벤토리부터
제가 지금 쓰는 순서는 이래요. 4단계면 끝납니다.
- 소비자를 먼저 센다 — 이 이벤트를 읽는 코드가 몇 곳인지 검색으로 확인해요. 저는 코드 그래프 인덱스로 한 번에 훑는데, grep 루프로도 됩니다. 중요한 건 "몇 개"라는 숫자를 손에 쥐는 거예요.
- 각 소비자의 기대 payload를 적는다 — 어떤 필드를 읽고, 어떤 값을 기대하는지 한 줄씩. 3~4개 넘어가면 표로 만들어 두는 게 편했어요.
- 양쪽 호환 기간을 둔다 — 새 필드를 추가하면서 옛 필드도 함께 보내는 구간을 만듭니다. 소비자가 전부 넘어온 걸 확인한 다음에 옛 필드를 지워요.
- 최종 상태까지 확인한다 — 발행 로그가 아니라, 사용자나 운영자가 보는 화면까지 가서 값이 바뀌었는지 눈으로 봅니다.
4번을 건너뛰면 이 글의 사고가 그대로 재현돼요. 저도 이번에 그래서 당했습니다.
unknown 레인을 만들어 두세요
가장 효과가 컸던 대비책은 의외로 단순했어요. 소비자 쪽 분기에 "어디에도 안 걸린 경우"를 명시적으로 만들고 로그를 남기는 것입니다.
switch (event.status) {
case "active":
return handleActive(event);
case "paused":
return handlePaused(event);
default:
// 조용히 버리지 말고 남긴다
logger.warn("unknown event status", {
status: event.status,
eventId: event.id,
});
return;
}default 에서 그냥 return 만 하면 그게 바로 조용한 죽음이에요. 한 줄 로그를 추가해 놓고 테스트해 보면, 필드가 안 맞을 때 즉시 보입니다. 저는 이걸 넣은 뒤로 비슷한 미스매치를 두 번 더 잡았어요.
여기에 하나 더 얹으면, 발행 시점에 스키마 검증을 걸어 두는 것도 좋아요. 런타임 스키마로 payload를 한 번 통과시키면 필드명 오타 같은 건 발행 전에 걸립니다.
경계를 넘는 데이터는 계약이에요
같은 레포 안의 함수 호출이면 타입 체커가 잡아 줘요. 그런데 이벤트나 webhook으로 프로세스 경계를 넘어가는 순간, 그 계약을 지켜 주는 건 아무도 없습니다. 컴파일러도, 테스트도, 발행 로그도요.
그래서 저는 요즘 이런 변경을 DB 스키마 변경과 같은 무게로 다룹니다. 플랜비(plan-b)에서 회비 상태 변경 이벤트를 다룰 때도 마찬가지예요. 출전 로테이션이 회비 상태를 읽는 구조라, 필드 하나 바꾸려면 로테이션 쪽 코드를 먼저 열어 봅니다. 귀찮지만 이게 제일 싸요.
같은 프로세스 안의 함수 호출 vs 프로세스 경계를 넘는 이벤트 계약
정리하면 한 문장이에요. 발행 로그의 초록색을 믿지 말고, 실제로 값이 바뀐 화면을 보세요. 대시보드와 현장이 충돌하면 현장이 맞습니다.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.