Spring Integration JMS Poller能否在轮询间保留IBM MQ会话?
IBM MQ轮询句柄状态问题解答
这是预期行为吗?
是,这是当前配置下的正常表现。你用的Jms.inboundAdapter搭配固定延迟轮询器,默认每次轮询都会走完整的创建-销毁流程:
- 新建JMS连接、会话和消费者
- 尝试拉取队列消息
- 不管有没有拿到消息,处理完就立刻关闭所有相关资源
所以轮询结束后队列句柄会被释放,MQ Explorer里就看不到了;下一次轮询启动时重新创建,句柄又会出现,这完全符合默认配置的逻辑。
能不能在轮询之间保留队列会话?
可以,通过缓存ConnectionFactory和调整轮询配置就能实现会话复用,避免每次轮询都重建资源。
具体改法:
换成带缓存的ConnectionFactory
Spring提供的CachingConnectionFactory可以缓存连接、会话和消费者,把它套在你的IBM MQ原生ConnectionFactory外面就行:@Bean public ConnectionFactory cachingConnectionFactory(ConnectionFactory mqConnectionFactory) { CachingConnectionFactory cachingConnFactory = new CachingConnectionFactory(mqConnectionFactory); cachingConnFactory.setCacheConsumers(true); // 开启消费者缓存,这是关键 cachingConnFactory.setSessionCacheSize(1); // 按需设置缓存的会话数量 return cachingConnFactory; }之后把这个
cachingConnectionFactory注入到Jms.inboundAdapter里,代替原来的原生连接工厂。调整轮询器的接收超时
给轮询器加上receiveTimeout,让消费者在会话保持的状态下等待消息,而不是每次轮询都重新初始化:IntegrationFlows.from( Jms.inboundAdapter(cachingConnectionFactory).destination(myQueue), e -> e.poller(Pollers.fixedDelay(Duration.ofMillis(1000)) .receiveTimeout(Duration.ofMillis(500))) // 超时前保持会话不销毁 ) .log(INFO, "Read Queue " + myQueue, m -> m) .channel(myDirectChannel) .get();这样配置后,会话和消费者会被缓存下来,轮询间隔期间不会被销毁,MQ Explorer里就能看到持续存在的队列句柄了。
额外注意点
CachingConnectionFactory默认会为每个线程分配独立的会话,不用担心多线程轮询的线程安全问题。- 你用的spring-integration-jms 5.5.7和IBM MQ客户端9.1.5完全支持这套配置,没有版本兼容问题。
内容的提问来源于stack exchange,提问作者lafual
相关产品推荐
相关产品推荐

