我有一个使用STOMP over WebSockets通信的Spring Boot应用程序(Jhipster),最近添加了一个ActiveMQ服务器来处理水平扩展,使用Amazon自动缩放组/负载均衡器。我使用
通过检查
我还发现在CONNECT / SUBSCRIBE帧中设置ActiveMQ特定的STOMP属性可以创建持久订阅者(可能性)。如果我设置了这些属性,Spring是否会理解路由?
convertAndSendToUser()
方法,它适用于单个应用程序实例,以定位经过身份验证的用户的“个人队列”,以便只有他们收到消息。然而,当我在负载均衡器后面启动应用程序时,我发现只有在生成他们的websocket代理连接(到代理)所在的服务器上的事件时,消息才会被发送给用户。如何确保消息通过ActiveMQ传递到用户实际“连接”的应用程序实例,而不管哪个实例接收到执行convertAndSendToUser()
事件的HTTP请求?以下是我的StompBrokerRelayMessageHandler供参考:@Bean
public AbstractBrokerMessageHandler stompBrokerRelayMessageHandler() {
StompBrokerRelayMessageHandler handler = (StompBrokerRelayMessageHandler) super.stompBrokerRelayMessageHandler();
handler.setTcpClient(new Reactor2TcpClient<>(
new StompTcpFactory(orgProperties.getAws().getAmazonMq().getStompRelayHost(),
orgProperties.getAws().getAmazonMq().getStompRelayPort(), orgProperties.getAws().getAmazonMq
().getSsl())
));
return handler;
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableStompBrokerRelay("/queue", "/topic")
.setSystemLogin(orgProperties.getAws().getAmazonMq().getStompRelayHostUser())
.setSystemPasscode(orgProperties.getAws().getAmazonMq().getStompRelayHostPass())
.setClientLogin(orgProperties.getAws().getAmazonMq().getStompRelayHostUser())
.setClientPasscode(orgProperties.getAws().getAmazonMq().getStompRelayHostPass());
config.setApplicationDestinationPrefixes("/app");
}
通过检查
SessionSubscribeEvent
中的标头,我已经找到了与ActiveMQ生成的队列对应的名称,这是在用户订阅用户队列时侦听器中生成的,称为simpSessionId
。@Override
@EventListener({SessionSubscribeEvent.class})
public void onSessionSubscribeEvent(SessionSubscribeEvent event) {
log.debug("Session Subscribe Event:" +
"{}", event.getMessage().getHeaders().toString());
}
在ActiveMQ中可以找到相应的队列,格式为:{simpDestination}-user{simpSessionId}
我能否将sessionId保存在键值对中,然后只是将消息推送到该主题通道上?
我还发现在CONNECT / SUBSCRIBE帧中设置ActiveMQ特定的STOMP属性可以创建持久订阅者(可能性)。如果我设置了这些属性,Spring是否会理解路由?
client-id
和subcriptionName
。