이 시리즈는 채팅 시스템을 구축하면서 겪은 경험을 정리한 기술 회고로,
해당 글은 채팅에서 사용한 기술을 선택한 이유와 MVP를 위해 가장 먼저 구축했던 RDB 기반 채팅 시스템에 대해 다룹니다.
팀 프로젝트를 진행하면서, AI 기반 전자기기 중고거래 플랫폼을 개발하게 되었습니다. 저는 백엔드를 담당하며, 채팅파트를 맡아 진행했습니다.
이에, 가장 먼저 사용할 기술에 대해 고려했고, 여러 후보 중 STOMP와 Redis를 선택했습니다.
기획단계에서 나왔던 요구사항이 다음과 같이 나왔고, 이에 맞춰서 진행했습니다.
1. 메시지 실시간 송수신
2. 채팅방 단위로 마지막 메세지를 보여주기
3. 각 사용자별로 읽은 메시지 정보 제공
4. 실시간으로 읽음여부를 파악


chat_message 테이블에 시간 순으로 쌓입니다.read_point는 사용자가 마지막으로 읽은 메시지를 기준으로 읽음 여부를 계산하는 데 사용됩니다.메시지는 WebSocket으로 수신되며, 바로 JPA를 통해 DB에 저장합니다.
@Slf4j
@Component
@RequiredArgsConstructor
public class StompChannelInterceptor implements ChannelInterceptor {
private final Map<String, Set<String>> sessions = new ConcurrentHashMap<>();
@Override
public Message<?> preSend(@NonNull Message<?> message, @NonNull MessageChannel channel) {
StompHeaderAccessor accessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
// 올바른 접근인 지 판단
switch (accessor.getCommand()) {
case CONNECT -> {
handleConnect(accessor);
}
case SEND -> {
handleSend(accessor, message);
}
case DISCONNECT -> {
handleDisconnect(accessor);
}
}
return message;
}
private void handleDisconnect(StompHeaderAccessor accessor) {
//연결 종료 시, 행동할 메소드
}
private void handleSend(StompHeaderAccessor accessor, Message<?> message) {
// 전송 시, RDB에 저장
private void handleConnect(StompHeaderAccessor accessor) {
// 연결 시, jwt 검증 시도
}
}
SSAFY 프로젝트로 아직 반출신청을 못해서...
지금은 큰 로직만 보여드리고, 추후에 자세한 코드를 첨부하겠습니다.


예상대로 Chatting 조회 테스트를 진행하면서, 메시지 건수를 늘렸더니 속도가 저하되었습니다. 그래서 1차적으로 Slice<>를 통한 필요한 데이터만 return하도록 구성했고, 캐시 구성을 위한 Redis 기반의 채팅으로 전환을 진행했습니다.
RDB로 간단한 MVP를 구성했으니, 이제는 RDB에서 Redis로 전환하면서 속도를 높인 로직으로 바꿔보겠습니다.