Spring+WebSocket+STOMP集成Amazon MQ代理中继失败问题排查
解决Spring Boot连接Amazon MQ(ActiveMQ)作为STOMP中继的问题
核心问题分析
'\r' must be followed by '\n'错误:误用了OpenWire协议端口(61617),StompBrokerRelay需与STOMP协议端口(61614)通信,用STOMP解码器解析OpenWire协议响应必然格式不兼容。- SSL握手超时:Netty客户端SSL配置未正确处理Amazon MQ的SSL证书,导致握手失败。
Message broker not active错误:未启用SSL连接到Amazon MQ的SSL端口,实际连接未建立成功。
正确配置方案
1. 修改application.properties
切换到STOMP SSL端口:
relay.host=abc.amazonaws.com relay.port=61614 # 使用STOMP SSL端口 relay.host.user=myuser relay.host.password=mypwd
2. 正确配置WebSocketConfig
配置支持SSL的ReactorNettyTcpClient,确保SSL上下文正确处理Amazon MQ证书:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Value("${relay.host}") private String host; @Value("${relay.port}") private int port; @Value("${relay.host.user}") private String user; @Value("${relay.host.password}") private String password; @Override public void configureMessageBroker(MessageBrokerRegistry registry) { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(1); threadPoolTaskScheduler.initialize(); threadPoolTaskScheduler.setThreadNamePrefix("wss-heartbeat-thread-"); // 配置支持SSL的Netty客户端,测试环境可使用默认信任库 ReactorNettyTcpClient<byte[]> client = new ReactorNettyTcpClient<>( tcpClient -> tcpClient .host(host) .port(port) .sslContext(SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) // 测试用,生产需替换为信任AWS CA的配置 .build()), new StompReactorNettyCodec() ); registry.enableStompBrokerRelay("/queue/", "/topic/") .setTcpClient(client) .setAutoStartup(true) .setClientLogin(user) .setClientPasscode(password) .setSystemLogin(user) .setSystemPasscode(password) .setTaskScheduler(threadPoolTaskScheduler); registry.setApplicationDestinationPrefixes("/app"); registry.setPreservePublishOrder(true); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy(); registry.addEndpoint("/chat") .setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy)) .setAllowedOrigins("*"); } @Override public void configureClientInboundChannel(ChannelRegistration registration) { registration.interceptors(new AuthChannelInterceptor()); } }
3. 生产环境SSL配置优化
测试环境的InsecureTrustManagerFactory不适合生产,需导入Amazon MQ的CA证书到JVM信任库,或显式指定信任证书:
// 生产环境示例:加载AWS CA证书文件 Path certPath = Paths.get("path/to/amazon-mq-ca.pem"); SslContext sslContext = SslContextBuilder.forClient() .trustManager(certPath.toFile()) .build();
证书可从Amazon MQ控制台下载,参考AWS官方文档获取具体证书文件。
4. 连接验证
启动应用后,检查日志是否出现以下成功连接标识:
INFO ... o.s.m.s.s.StompBrokerRelayMessageHandler : TCP connection established in session _system_
若仍有握手超时,需排查:
- 服务器安全组是否开放61614端口给应用服务器IP
- 应用服务器是否能访问Amazon MQ端点(用
telnet abc.amazonaws.com 61614测试连通性) - SSL上下文配置是否正确
关键注意点
- 必须使用STOMP协议端口(61614),StompBrokerRelay基于STOMP协议与代理通信,不能用OpenWire端口。
- Amazon MQ的STOMP端口默认SSL加密,必须配置SSL连接,不能使用普通TCP。
- 确保Spring Boot版本与Netty、Reactor Netty版本兼容(Spring Boot 2.7.x对应Reactor Netty 1.0.x)。
内容的提问来源于stack exchange,提问作者SelvarajKumarasamy
相关产品推荐
相关产品推荐

