You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring+WebSocket+STOMP集成Amazon MQ代理中继失败问题排查

解决Spring Boot连接Amazon MQ(ActiveMQ)作为STOMP中继的问题

核心问题分析

  1. '\r' must be followed by '\n'错误:误用了OpenWire协议端口(61617),StompBrokerRelay需与STOMP协议端口(61614)通信,用STOMP解码器解析OpenWire协议响应必然格式不兼容。
  2. SSL握手超时:Netty客户端SSL配置未正确处理Amazon MQ的SSL证书,导致握手失败。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:42:01