Post

루퍼스 8주차 WIL

루퍼스 8주차 WIL

이번 주 핵심 인사이트

1. Kafka와 Consumer 사이의 Pull 방식이 중요한 이유

Consumer는 Kafka에서 메시지를 Pull 방식으로 가져간다. Pull 방식이라 Consumer가 자기 처리 능력만큼만 가져갈 수 있고, 처리가 끝나면 offset을 커밋해서 “여기까지 읽었다”를 기록한다.

2. Consumer에서 멱등성이 중요한 이유

Producer가 중복 발행을 막아도 Consumer에게는 같은 메시지가 여러 번 전달될 수 있다. Consumer가 메시지 처리 후 offset 커밋 전에 죽거나 리밸런싱이 일어나면, 재시작 시 같은 메시지를 다시 받는다. 그래서 “같은 이벤트가 여러 번 와도 결과는 1번만 반영”되도록 멱등 처리가 필수였다.

3. Transactional Outbox가 필요한 이유

DB 트랜잭션은 성공했는데 메시지 발행이 실패하면? 이벤트가 유실된다. 유실된 메시지를 찾을려면 어딘가 저장이 필요하다. DB와 Kafka는 서로 다른 시스템이라 하나의 트랜잭션으로 묶을 수 없기 때문에, “보낼 이벤트”를 Outbox 테이블에 먼저 저장해두는 패턴이 필요했다.

4. 집계에서 “최신 이벤트만 반영”이 항상 정답은 아니다

상태성 이벤트(재고 소진 등)는 최신 상태만 중요할 수 있다. 하지만 좋아요 등록/해제처럼 상태별 집계가 필요한 경우는 다르다. 최신 이벤트만 보면 중간에 발생한 등록/해제 이력이 사라진다. 이벤트 성격에 따라 “최신만 반영” vs “모든 이벤트 누적”을 구분해야 한다는 걸 배웠다.

5. 재시도 가능한 예외와 불가능한 예외를 구분해야 한다

Kafka 인증/접속 오류나 serialization 오류가 발생하면 백날 재시도해도 같은 에러가 난다. 이런 예외는 재시도 대신 로그 남기고 스킵하거나 DLQ로 보내는 게 맞다. 반면 일시적인 네트워크 타임아웃은 재시도로 복구될 수 있다. 예외 유형을 구분해서 처리 전략을 다르게 가져가야 한다.

6. 다음 글은 좀 더 깊게 써보자

이번 블로그 글은 Outbox, 멱등 Consumer 등 전체 구조를 훑는 데 집중했다. 다음 주 글은 랭킹 중 어떤 한 부분에 대해 좀 재미있고, 깊이 있는 글을 써봐야지!

This post is licensed under CC BY 4.0 by the author.