-
Spring WebSocket External Broker 적용(ActiveMQ)프로젝트/WebSocket 2023. 7. 21. 00:01반응형
개요
In-memory Broker인 SimpleBroker를 사용하게 되면 Server Instance가 여러 대 존재할 때 상태에 대한 동기화가 제대로 이루어지지 않을 수 있습니다.
예를 들어, A유저는 Server1에서 웹소켓을 연동하였고, B유저는 Server2에서 웹소켓을 연동하였습니다. 만약 같은 /topic/same을 바라본다고 하더라도 Server1에서 message를 보내면 A만 받을 수 있을 것이며, Server2에서 message를 보내면 B만 받을 수 있습니다.
이에 따라 External Broker를 적용해보고자 합니다.
RabbitMQ, ActiveMQ 등을 적용해 볼 수 있습니다.
External Broker를 활용한 STOMP 구조도
https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/html/websocket.html SimpleBroker를 이용한 구조에서 바뀐 부분은 바로 StompBrokerReplay가 MessageHandler부분에 적용되는 것입니다.
Broker Relay를 사용하여 TCP를 통해 외부 STOMP 브로커로 메시지를 전달하고 브로커에서 가입한 클라이언트로 메시지를 전달합니다.
//Simple Broker를 사용하는 경우 config.enableSimpleBroker("/queue") //Relay를 활용하여 External Broker를 사용하는 경우 config.enableStompBrokerRelay("/queue");
StompBrokerRelayMessageHandler 동작과정
1. CONNECT 메시지마다 브로커와 TCP 연결 수립 (session-id로 식별)
2. 모든 메시지 브로커로 전달
3. 브로커로부터 받은 메시지를 WebSocket 세션을 통해 클라이언트에게 전달
RabbitMQ vs ActiveMQ
STOMP를 지원하는 Message Broker 중 RabbitMQ와 ActiveMQ를 비교해보고자 합니다.
Spring docs에서도 External Broker의 예시로 RabbitMQ와 ActiveMQ 등등.. 으로 표기합니다.
RabbitMQ는 오픈소스 메시지 브로커로서 AMQP 프로토콜을 구현합니다.
plugin을 통해 MQTT, STOMP등의 프로토콜을 사용할 수 있습니다.
처리량이 많고 지연 시간이 짧은 메시징을 위해 설계되었습니다.
ActiveMQ는 JMS API를 지원하는 오픈소스 메시지 브로커입니다.
AMPQ, MQTT, STOMP 등 다양한 메시징 프로토콜을 지원합니다.
RabbitMQ은 단순성과 사용 편의성이 강조되며, ActiveMQ는 학습곡선이 조금 존재하지만 세분화된 제어, 고급 메시지 기능이 존재합니다.
더 다양한 기능으로 추후의 요구사항을 반영할 수 있는 ActiveMQ를 활용해 보겠습니다.
Docker Compose로 ActiveMQ 띄우기
version: '3.7' services: activemq: image: rmohr/activemq ports: - 8161:8161 - 61613:61613
http://localhost:8161/
admin, admin입력하여 접속
Spring MessageHanlder 코드 변경
override fun configureMessageBroker(config: MessageBrokerRegistry) { config.setApplicationDestinationPrefixes("/pub") config.enableStompBrokerRelay("/sub") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("admin") .setClientPasscode("admin") // config.enableSimpleBroker("/sub") }
enableSimpleBroker는 주석처리하고, enableStompBrokerRelay로 설정하였습니다.
Caused by: java.lang.IllegalStateException: No compatible version of Reactor Netty
이후 실행하면 위와 같은 예외가 발생합니다.
reactorNettyClientPresent = ClassUtils.isPresent("reactor.netty.http.client.HttpClient", classLoader); reactorNetty2ClientPresent = ClassUtils.isPresent("reactor.netty5.http.client.HttpClient", classLoader);
예외난 부분의 코드를 타고 들어가 확인해 보니 내부적으로 Reactor Nettry가 외부 메시지 브로커와의 연결 및 통신 설정을 위해 기본적으로 사용되고, reactor.netty와 관련된 의존성이 없어 발생한 예외 같습니다.
implementation("org.springframework.boot:spring-boot-starter-reactor-netty")
위의 의존성 추가 후 다시 실행
Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'
implementation("io.netty:netty-resolver-dns-native-macos:4.1.72.Final:osx-aarch_64")
github issues를 살펴보니 netty를 사용할 때 MacOS에서 DNS 문제를 해결하기 위해 위의 의존성을 추가하면 된다고 합니다.
TCP connection failure in session _system_: Failed to connect: Connection refused: localhost/127.0.0.1:61613
docker부분에서 port binding 하는 부분에 61616으로 되어 있어 61613으로 수정 후 잘 실행됩니다.
Client로 접속하여 Connect!
ActiveMQ에 Queue가 하나 생겼다
Test로 해당 토픽을 Consumer가 구독하도록 하고, 메시지를 발행하면?
메시지가 정상적으로 도달하여 External Broker가 잘 동작하는 것이 확인가능하다.
참고자료
https://docs.spring.io/spring-framework/reference/web/websocket/stomp/handle-broker-relay.html
External Broker :: Spring Framework
The simple broker is great for getting started but supports only a subset of STOMP commands (it does not support acks, receipts, and some other features), relies on a simple message-sending loop, and is not suitable for clustering. As an alternative, you c
docs.spring.io
https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/html/websocket.html
26. WebSocket Support
This part of the reference documentation covers Spring Framework’s support for WebSocket-style messaging in web applications including use of STOMP as an application level WebSocket sub-protocol. Section 26.1, “Introduction” establishes a frame of m
docs.spring.io
https://www.rabbitmq.com/documentation.html
Documentation: Table of Contents — RabbitMQ
Documentation: Table of Contents This page summarises the available RabbitMQ documentation for the latest patch release. Installation See the Downloads and Installation page for information on the most recent release and how to install it. Tutorials See th
www.rabbitmq.com
https://www.designgurus.io/blog/RabbitMQ-Kafka-ActiveMQ-System-Design
RabbitMQ vs. Kafka vs. ActiveMQ: A Battle of Messaging Brokers
Comparing Features, Performance, and Use Cases of Top Messaging Brokers.
www.designgurus.io
'프로젝트 > WebSocket' 카테고리의 다른 글
Spring Boot WebSocket with Kafka (0) 2023.07.28 RSocket이란? (0) 2023.07.20 WebSocket Scale Out - 이론편 (0) 2023.06.24 TCP Socket vs WebSocket (0) 2023.06.23 Spring WebSocket 활용 (0) 2023.06.12