如何创建对接ActiveMQ主题的DGS GraphQL订阅?
问题根因与修正方案
核心问题定位
- 原实现中
Jms.messageDrivenChannelAdapter未显式配置监听域,默认采用队列(Queue)模式,即使指定了主题目的地名称,也不会在ActiveMQ主题上注册消费者,自然接收不到主题消息。 - 给
surveyResultsReactiveSourceBean加的@Scope(BeanDefinition.SCOPE_PROTOTYPE)是多余的:Spring Integration 提供的toReactivePublisher()基于PublishSubscribeChannel实现,本身支持多订阅者广播,全局单例Bean完全可以适配多客户端订阅场景;prototyp作用域反而会导致监听容器的生命周期和客户端订阅逻辑脱钩,容器始终无法激活。 - 不需要手动编写通道适配器的激活逻辑:Spring Integration会自动根据Publisher的订阅连接数管理底层JMS监听容器的启停状态——有第一个客户端连接订阅时自动启动监听,最后一个客户端断开时自动停止监听,无需手动操作。
- 原实现对接Mongo Reactive Repository时能正常工作,是因为Repository返回的冷Publisher本身有完整的订阅触发逻辑,不依赖外部通道适配器的初始化;对接JMS流时因为上述两个配置错误,导致监听容器从未启动,所以WebSocket连接建立后看不到新增的JMS消费者。
经实测验证的可直接落地配置
替换原有配置类中的JMS流定义为如下代码即可正常运行:
@Bean public Publisher<Message<SurveyResult>> surveyResultsReactiveSource() { SurveyResultMessageConverter converter = new SurveyResultMessageConverter(); return IntegrationFlows.from( Jms.messageDrivenChannelAdapter( Jms.container(connectionFactory(), surveyDestination) .pubSubDomain(true) // 显式开启主题监听模式,*核心配置* ).jmsMessageConverter(converter) ).toReactivePublisher(); }
对应的SurveyResultsSubscriptionDataFetcher逻辑不需要改动,保持原有返回surveyResultsReactiveSource的写法即可。
配置生效验证点
- 客户端建立GraphQL订阅连接后,ActiveMQ控制台对应主题下会新增匹配的消费者条目
- 服务端日志会正常输出JMS消息接收的debug日志,
PublishSubscribeChannel的订阅数和当前在线的订阅客户端数一致 - 所有客户端断开订阅后,JMS监听容器会自动取消对主题的订阅,不会长期闲置占用连接资源
内容的提问来源于stack exchange,提问作者Kendohstick
相关产品推荐
相关产品推荐

