채팅 서비스, 왜 Pub/Sub인가? Redis가 완성시키는 Spring boot 기반 채팅 서비스 공부 기록
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
웹 개발
대상자 대상자_정보 출력
- Spring Boot 및 실시간 웹 개발자
- 중간 이상의 Java/JavaScript 경험자
- Redis와 WebSocket을 활용한 아키텍처 설계 관심자
핵심 요약
- WebSocket + STOMP 를 통해 실시간 양방향 통신 구현
- Redis Pub/Sub 을 메시지 브로커로 사용하여 확장성 및 성능 보장
- RDBMS 를 통해 메시지 영속성 보완
섹션별 세부 요약
### > 1. 서론: 왜 실시간 채팅인가? 그리고 아키텍처의 중요성
- 사전 인식의 오류 : 단순 DB 기반 채팅은 새로고침 필요
- 핵심 요구사항 :
- 실시간성 (채팅 즉시 반영)
- 확장성 (다수 사용자 대응)
- 메시지 보장성 (유실 방지)
- 초기 설계의 중요성 : 잘못된 아키텍처는 기술 부채로 이어짐
### > 2. 실시간 통신 기술 선택: WebSocket이 답이었다
- WebSocket 선택 이유:
- HTTP 오버헤드 제거
- 양방향 통신 가능
- 성능 효율성 (Polling/SSE 대비)
- SockJS 도입:
- 구형 브라우저 호환성 보장
- HTTP 스트리밍/롱 폴링 폴백 가능
- STOMP 도입:
- 메시지 라우팅 (예:
chat:room:123
) - Spring WebSocket 및 STOMP.js 지원
### > 3. 메시지 브로커 선택: Redis Pub/Sub의 매력
- Redis Pub/Sub 장점:
- 인메모리 기반 (속도 빠름)
- 다중 서버 브로드캐스팅 가능
- 구현 간단 (Kafka 대비)
- 단점:
- 메시지 영속성 없음 (RDBMS 사용)
- 전달 보장성 낮음 (재전송 로직 추가)
- 구조 설계:
- Redis : 실시간성 확보
- RDBMS : 영속성 및 이전 기록 제공
### > 4. 아키텍처 최종 구상 및 데이터 흐름
- 데이터 흐름:
- SockJS + STOMP.js로
/ws/chat
연결 - STOMP 구독 (
/sub/chat/room/{roomId}
) - 메시지 발행 (
/pub/chat/message
) - RedisTemplate을 통해 Redis Pub/Sub에 메시지 발행
- RedisMessageListenerContainer로 메시지 수신 후 ChatService로 전달
- RDBMS에 메시지 영구 저장
- REST API : 이전 채팅 기록 조회 지원
### > 5. 백엔드 구현: Spring Boot 기반 (1/2) - 기본 설정 및 WebSocket/STOMP
- 의존성 추가:
spring-boot-starter-websocket
spring-boot-starter-data-redis
spring-boot-starter-data-jpa
- WebSocketConfig.java 핵심 설정:
@EnableWebSocketMessageBroker
활성화config.setApplicationDestinationPrefixes("/pub")
config.enableSimpleBroker("/sub")
registry.addEndpoint("/ws/chat").withSockJS()
결론
- WebSocket + STOMP + Redis Pub/Sub 구조로 고확장성 채팅 서비스 구현
- Redis의 단점(영속성, 보장성)은 RDBMS와 재전송 로직으로 보완
- SockJS로 브라우저 호환성 확보, STOMP로 메시지 라우팅 효율화
- Spring Data Redis와 @MessageMapping 활용하여 메시지 흐름 명확히 설계