이번에 진행하는 프로젝트에서 채팅 서버 관련 개발을 담당하게 되어 학습한 내용을 정리한 포스팅입니다.
채팅 서버 관련 레퍼런스를 참조하며 클론코딩을 진행해보는 과정에서 아래와 같은 문제점을 발견했습니다.
단순 WebSocket만을 통해 채팅 서버를 구현하게 될 경우
- 해당 메시지가 어떤 요청인지
- 어떻게 처리해야 하는지에 따라 채팅룸과 세션을 일일이 구현해야함
- 메시지 발송을 관리하는 추가 코드 필요
이런 단점들을 STOMP 프로토콜을 활용하여 메시징을 효율적으로 처리하여 서버를 고도화할 필요가 있다고 생각했고 다음은 학습한 내용을 정리한 부분입니다.
STOMP
STOMP란?
- Simple Text Oriented Messaging Protocol
- 메시지 전송을 효율적으로 하기 위한 프로토콜
- 기본적으로 Publish-Subscribe 구조
- 클라이언트/서버 간 전송할 메시지의 유형, 형식, 내용들을 정의한 규칙
- 헤더 값을 기반으로 통신 시 인증처리를 구현할 수 있음
-- JWT, Spring Secure 등..
- OSI 4계층 TCP 및 WebSocket 같은 양방향 네트워크 프로토콜 기반 동작
STOMP 프로토콜 활용 시 장점
1. Messaging Protocol을 만들고 메세지 형식을 커스터마이징 할 필요가 없음.
2. Message Broker를 이용해, Subscription(구독)을 관리하고 메세지를 브로드캐스팅할 수 있음.
3. RabbitMQ, Redis, Kafka 같은 Message Broker를 이용해, Subscription(구독)을 관리하고 메세지를 브로드캐스팅할 수 있다.
STOMP Frame
COMMAND
header1 : value1
header2 : value2
Body^@
COMMAND : 메세지의 타입을 나타내는 문자열이다. 아래에 추가로 정리
header1, header2 : 추가 정보를 제공하는 헤더이다.
- destination : 이 헤더(토픽)로 메세지를 보내거나(SEND), 구독(SUBSCRIBE)할 수 있다.
Body : 메세지의 내용이다.
^@ : NULL 문자이다. Body의 끝을 나타낸다. (이 친구 때문에 POSTMAN 테스트가 안되는 듯 하다…)
추가 Frame 정리
STOMP 1.2 클라이언트는 다음 헤더를 설정할 수 있습니다
- login: STOMP 서버에 대해 인증하는 데 사용되는 사용자 식별자입니다.
- passcode: STOMP 서버에 대해 인증하는 데 사용되는 비밀번호입니다.
- heart-beat: heart-beating Config
login 및 passcode를 활용한 보안 강화를 진행할 수 있음.
heart-beat의 경우 TCP 연결의 상태를 테스트하고 원격 End-Point가 살아 있고 작동하는지 확인하는 데 사용될 수 있음.
COMMAND
- CONNECT
- SEND
- SUBSCRIBE
- UNSUBSCRIBE
- BEGIN
- COMMIT
- ABORT
- ACK
- NACK
- DISCONNECT
Message Broker
- Publisher로 부터 전달받은 메시지를 Subscriber에게 메시지를 주고 받게 해주는 중간 역할
- 메시지의 발행자와 이용자 사이에 일대다 관계가 형성되는 브로드캐스트 스타일의 배포 방법
동작 흐름
메시지 브로커에는 토픽(==Channel)이란 개념이 존재함.
이는 Publisher와 Subcriber 사이에서 우체통 역할을 수행하는데,
Publisher가 특정 토픽에 대해 메시지를 발행하면 해당 토픽을 구독하고 있는 모든 Subcriber에게 메시지를 브로커가 전달하는 느낌으로 동작.
Message 플랫폼
https://docs.spring.io/spring-framework/reference/web/websocket/stomp/handle-broker-relay.html
해당 Spring 레퍼런스를 참조해보면 알 수 있듯
Spring에서 STOMP를 간단하게 사용할 때 SimpleBroker를 사용할 수 있는데 간단한 메시지 전송 루프에 의존하며 클러스터링에 적합하지 않음.
또한 내부 Simple 브로커를 사용하게 될 경우 서버의 자원을 추가로 사용하는 단점 및 서버가 N대일 때 서로 상호 유기적인 동기화가 안된다는 점 등 단점이 다수 있음.
따라서 Spring에서는 External Broker를 사용하여 애플리케이션을 업그레이드하길 추천하고 있음.
외부 메시지 브로커에는 Redis, RabbitMQ, ActiveMQ, Kafka 등등 여러 플랫폼이 존재함.
아래는 외부 브로커 Kafka와 Redis의 차이점을 나열
Apache Kafka | Redis | |
메시지 크기 | 압축 및 계층형 스토리지로 최대 1GB의 메시지 크기를 지원합니다. | 더 작은 메시지 크기를 지원합니다. |
메시지 전송 | 구독자는 대기열에서 메시지를 가져옵니다. | Redis 서버는 연결된 가입자에게 메시지를 푸시합니다. |
메시지 보존 | 검색 후 메시지를 보존합니다. | 메시지를 보관하지 않습니다. |
오류 처리 | 메시징 수준에서의 강력한 오류 처리. 배달 못한 편지 대기열, 이벤트 재시도 및 리디렉션. | 제한 시간, 클라이언트 제한 및 메모리 버퍼 용량을 사용하여 애플리케이션 수준에서 Redis 예외를 처리해야 합니다. |
병렬 처리 | Kafka는 병렬 처리를 지원합니다. 여러 소비자가 동일한 메시지를 동시에 검색할 수 있습니다. | 병렬 처리를 지원하지 않습니다. |
처리량 | 비동기 읽기/쓰기로 인해 처리량이 더 높습니다. | Redis 서버가 다른 구독자에게 메시지를 보내기 전에 회신을 기다려야 하기 때문에 처리량이 줄어듭니다. |
지연 시간 | 짧은 지연 시간. 기본적으로 데이터 복제로 인해 Redis보다 약간 느립니다. | 작은 크기의 메시지를 배포할 때 지연 시간이 매우 짧습니다. |
내결함성 | 파티션을 다른 브로커에 자동으로 백업합니다. | 기본적으로 백업되지 않습니다. 사용자는 Redis 지속성을 수동으로 활성화할 수 있습니다. 소규모 데이터 손실 위험. |
학습 정리
채팅 서버 관련 다양한 레퍼런스를 찾는 과정에서 STOMP, Broker, Kafka, Redis 등등 자주 접해보지 못한 용어들에 대해 하나하나 찾아보며 배우면서 나름 알차게 배운 것 같다.... (아직 머릿속이 조금 어지럽긴 하지만)
참고로 서버단만 개발을 우선 진행하고 POSTMAN 통해서 테스트를 해보려 했지만 ^@(NULL)문자 탓인지 제대로 연결이 되질 않고, 이전부터 STOMP 테스트에 사용되는 Apic이란것도 사용해보려 했지만 어느순간부터 웹앱 다운로드 url 접속이 되지않는다는걸 뒤늦게 알아차려 시간을 엄청 버리고 결국 프론트단도 테스트 개발을 진행했는데 정말 참고할 레퍼런스 및 오픈소스가 적다는게 얼마나 개발에 힘이 드는건지 알게 되었다...
소켓을 사용하여 채팅 애플리케이션을 학부 때 개발해본적이 있었긴 하지만 당시에는 제대로 정리하지 못하고 레퍼런스 긁어오기 급급했기에 제대로 배우질 못했는데,
이번 프로젝트를 계기로 채팅 관련 라이브러리 및 고도화 방법에 대해서 다양하게 접근해보고 배울 수 있을 것 같다.
추가로 이번 개발을 진행하면서 WebSocket 관련 사용법 및 Config 방법, Redis와 같은 외부 브로커를 사용한 고도화 방법, 추가로 STOMP 헤더를 활용하여 Spring Secure 적용등을 통한 보안 강화방법등에 대해서 알아보고 포스팅 할 예정!
'Develop > SpringBoot' 카테고리의 다른 글
[Swagger] 스프링 3.x Swagger 적용(With. SpringDocs) (1) | 2024.01.31 |
---|---|
[SpringBoot] 웹소켓(WebSocket) (0) | 2024.01.31 |
[Jasypt] application.properties 설정 암호화 (0) | 2024.01.29 |
[채팅 서버] Springboot + STOMP를 활용한 채팅 구현 (1) | 2024.01.26 |
[SpringBoot] 스프링부트 프로젝트 Jar파일 생성 (0) | 2024.01.09 |
개발 기술 블로그, Dev
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!