spring - Spring Message Listener - 连接刷新
问题描述
我们已经用 spring 实现了一个消息监听器,容器配置如下所示
<bean id="customContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="${jms.customContainer.concurrentconsumers}" />
<property name="maxConcurrentConsumers" value="${jms.customContainer.maxconcurrentconsumers}" />
<property name="errorHandler" ref="errorHandler" />
<property name="connectionFactory" ref="jmsQueueConnectionFactory" />
<property name="destination" ref="listenerQueue" />
<property name="messageListener" ref="customContainerListener" />
<property name="receiveTimeout" value="1" />
<property name="sessionTransacted" value="true" />
<property name="transactionManager" ref="txManager" />
</bean>
它部署在 Jboss 和服务器日志中经常显示以下连接刷新消息。
org.springframework.jms.listener.DefaultMessageListenerContainer] (customContainer-3849) Successfully refreshed JMS Connection
据报道,托管 WebSphere MQ 的大型机端的 MSU/MIPS 利用率很高。这可能是导致频繁 MQ GET 调用和提高利用率的原因吗?
我们没有明确指定消息回复到,这会导致回复每次都尝试排队吗?接收超时也设置为 1 毫秒,这是否意味着它将每 1 毫秒主动轮询一次队列?有人可以解释一下这个概念吗?
解决方案
DefaultMessageListenerContainer
实现队列的轮询。这意味着它发出一个 GET 等待receiveTimeout
. 如果您有receiveTimeout
1ms 的时间,这意味着如果队列中没有消息并且将进行另一个 GET 调用,则每个 GET 调用将在 1ms 后返回。这对于队列管理器来说是背靠背的 GET 调用。
两种选择:
- 您可以增加
receiveTimeout
一个更高的数字,这将导致指定值的等待获取,例如,等待 60000 毫秒的获取只会每 1 分钟或在消息到达队列后执行一次获取。一旦将消息放入队列,您仍然可以从队列中获取消息。 - 如果可能,一个更有效的选择是切换到
SimpleMessageListenerContainer
将使用本机 JMS 异步侦听器的选项。对于 IBM MQ,这是通过 MQ 回调功能实现的。这意味着侦听器向队列管理器注册回调,并且队列管理器在新消息到达队列时通知侦听器,因此没有轮询。
推荐阅读
- regex - 在第一次出现逗号时将字符串拆分为 2 个子字符串?
- django - ImportError:无法导入名称模型
- apache-spark - spark 2.3 读取配置单元表始终为 0 行
- css - 使该网站内容水平适合且仅垂直溢出的最有效方法
- java - SQL 选择 JSON_OBJ 的 Java ResultSet 迭代
- java - 如何从自定义 ToolWindow 调用 IntelliJ 重命名重构?
- ios - 如何在 Swift 中返回 0 而不是 Nan?
- html - 使用 JQuery 修改 HTML 中的类名
- python - 为什么有些人将两个不同网络的参数链接起来并用相同的优化器训练它们?
- android - putBytes() 与 putFile() 用于上传图像