### 이벤트를 분리하는 건 알겠는데 어떤 메시지를 발행해야 하지 ?
이전에 '강의 모듈'과 '알림 모듈'을 분리하는 과정을 거쳤었습니다.
그런데 이벤트 기반 아키텍처(EDA)를 지향하는 데 있어서 카프카를 도입하고
그 과정에서 어떤 메시지를 발행해야 하는지 ..
구체적으로는 메시지에 어떤 내용을 담아야 좋을지에 대해서 고민했습니다.
이때, 제로 페이로드 방식과 이벤트 전달 상태 전송이라는 두 가지 방식 중 선택하고자 했습니다.
제로 페이로드 (Zero Payload)
- 방식: 이벤트에 ID만 담아 보냅니다. 예를 들어,
({ "type": "ACCEPTED", "enrollmentId": 123 })와 같이 최소한의 데이터만을 담습니다.
여기서 카프카 컨슈머가 상세 내용을 알기 위해 API 등을 활용해서 도메인 서버로 세부 데이터를 요청하기도 합니다. - 장점:
- 보통 최신 데이터를 조회하므로 순서 보장에 덜 민감합니다.
- 이벤트 스키마가 단순합니다.
- 외부 다른 도메인과의 의존관계를 좀 더 많이 덜어낼 수 있는 거 같습니다.
- 단점:
- 이벤트가 발생한 도메인에 대한 역방향 부하가 발생할 수 있습니다.
- 인기 강의 수강신청 시 수천 건의 조회가 동시에 몰리면 Course 서비스에 과도한 부하가 발생하는 경우입니다.
- "수강신청 요청" 알림인데, 조회하는 찰나에 "수강신청 취소"가 되었다면 ? 알림 내용과 실제 데이터가 달라질 수 있습니다.
- 이벤트가 발생한 도메인에 대한 역방향 부하가 발생할 수 있습니다.
이벤트 전달 상태 전송 (Event-Carried State Transfer)
- 방식: 알림 발송에 필요한 정보(제목, 내용 등)를 이벤트에 담아 보냅니다. 예를 들어,
누가 --> (학생이)
무엇을 하여 --> (수강신청을 요청하여)
누구에게 --> (강사의 강의에)
어떤 변화가 --> (요청이 가고)
정도의 데이터를 담는 것입니다.- 그래도 중요한 것은 이벤트에 담을 내용에는 '명령하는 성격의 어떠한 메시지(command)'를 담으면 안 된다는 것입니다.
- 이전까지 작성했던 코드를 보면 카프카로 발행할 메시지에 명령적 성격의 커맨드를 담아서 보낸 것 같습니다 ..
- 장점:
- 카프카 컨슈머가 세부 내용을 조회하려고 발행한 쪽의 도메인에 API 호출 등을 하지 않으므로 추가적인 부하가 없을 수 있습니다.
- 지금 도메인의 경우, "수강신청 요청 시점"의 강의 제목으로 알림을 보낼 수 있습니다.
나중에 제목이 바뀌어도, 신청 당시 제목으로 알림이 가는 것이 보통 더 자연스럽습니다. - API 재호출이 없으니 Course 서버가 메시지를 발행한 후 급작스럽게 다운되더라도
Notification 서버는 마지막 발행한 메시지까지는 동작할 수 있습니다.
- 단점:
- 발행하는 이벤트의 스키마가 무거워질 수 있습니다.
- 정보 변경 시 이벤트도 수정해야 할 수 있습니다.
### 이벤트 전달 상태 전송 (Event-Carried State Transfer) 방식을 선택
발행할 메시지에 추가적인 내용을 담는 것을 선택했습니다.
보통 이럴 때는 '주문(Order)'의 예시를 많이 드는 것 같은데
제 경우는 '알림(Notification)'의 경우인데 '주문(Order)'의 경우와 잘 들어 맞지 않는다고 느꼈고
발행할 메시지에 대해서는 추가적인 내용을 담더라도 제로 페이로드를 '지향'하는 트레이드 오프를 선택하고자 합니다.
"알림"은 과거의 사실을 통보하는 성격이 강합니다. 따라서 이벤트 발생 시점의 스냅샷 데이터(강의명, 변경 내용 등)를 이벤트 페이로드에 포함해서 보내는 것이 더 유리하다고 느꼈고(위에서 말한 장점 중 두 번째),
API 재호출의 경우는 강의 서버와 알림 서버 간의 데이터를 동기화하는 방식을 최적화하는 방향을 생각하고 있습니다.
단, 트레이드 오프를 완화하기 위해,
- 변하지 않는 정보 위주로 담기: studentId, lectureTitle(당시 제목), timestamp 등 ..
- 너무 큰 데이터는 제외: 강의 상세 설명(내용 본문 등)처럼 알림에 필요 없는 거대한 데이터는 빼고 보냅니다.
- 필요시에만 조회: 만약 알림에 "현재 대기 인원" 같은 실시간성 데이터가 꼭 필요하다면, 그때 API 조회합니다
- 이 경우에는 캐싱을 활용해 볼 수도 있을 것 같습니다.
'SSA > Back' 카테고리의 다른 글
| [SSA] 비동기 콜백 등록 후 스케줄러를 통해 Retry를 하게 될 경우 무한 루프에 빠진다 ..? (0) | 2025.12.13 |
|---|---|
| [SSA] 스케줄러를 통해 Retry를 하게 될 경우 트랜잭션 처리 (0) | 2025.12.11 |
| [SSA] Redis의 특징을 활용한 동시성 제어 (Redis 분산 락 아님) (0) | 2025.09.13 |
| [SSA] 특강 개설 시 선착순 동시성 이슈 해결 (2) | 2025.09.10 |
| [SSA] 수강 로직에 대한 간단한 고민 .. (0) | 2025.09.09 |