채팅 메세지를 보내면 RabbitMQ로 메세지 전송 후 MongoDB에 해당 메세지 백업 후 MySQL에 마지막으로 보낸 메세지와 날짜를 업데이트 한다.
이 3가지의 과정이 동기적으로 일어나므로, 이 또한 부하를 줄 수 있을 것으로 판단되어 비동기처리를 적용한다.
현재 RabbitMQ라는 메세지 큐를 사용하고 있기 때문에 비동기처리가 가능하다.
GET /api/v1/chat/rooms/{roomId}/messages 요청을 보낸다. (스크롤을 올릴 경우 ?lastMessageTimestamp=... 포함)ChatMessageController: 요청을 받아 ChatMessageReader(Service)를 호출한다.ChatMessageRepository: (roomId, timestamp) 복합 인덱스를 사용하여 MongoDB에서 과거 메시지를 효율적으로 조회(페이지네이션)한다.roomId에 대한 웹소켓 구독(subscribe)을 시작하여 실시간 메시지를 받을 준비 한다.실시간 전달과 영구 저장이 두 개의 경로로 나뉘어 동시에 처리된다.
[클라이언트 A] --(WebSocket SEND)--> [ChatController]
|
| (1. 메시지 발행)
V
[RabbitMQ Exchange]
|
+-----------------------------------+-----------------------------------+
| |
V (경로 A: 실시간 전달) V (경로 B: 비동기 저장)
[ChatMessageConsumer] --(2)--> [STOMP Broker] [ChatMessageBackupConsumer]
| |
| (3. 실시간 방송) | (4. 백그라운드 작업)
V V
[구독중인 모든 클라이언트 (A, B)] [MongoDB 저장 & RDBMS 업데이트]
ChatController는 findOrCreateRoom으로 roomId를 확정한 뒤, 받은 메시지를 RabbitMQ Exchange로 즉시 발행하고 자신의 역할을 마친다.ChatMessageConsumer가 메시지를 즉시 받아 STOMP 브로커를 통해 해당 roomId를 구독 중인 모든 클라이언트(A와 B 모두)에게 전달한다.