Spring 消息侦听器 - 连接刷新

Spring Message Listener - Connection Refresh

我们已经使用 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实现队列的轮询。这意味着它发出一个等待 receiveTimeout 的 GET。如果您的 receiveTimeout 为 1 毫秒,这意味着如果队列中没有消息,每个 GET 调用将在 1 毫秒后 return 并且将进行另一个 GET 调用。对于队列管理器来说,这将显示为背靠背 GET 调用。

两个选项:

  1. 您可以将 receiveTimeout 增加到一个更高的数字,这将导致 get with wait 指定值,例如,get with wait 60000 ms 只会每 1 分钟或在消息命中后执行一次 get队列。一旦将消息放入队列,您仍然会立即将它们从队列中取出。
  2. 如果可能的话,一个稍微更有效的选择是切换到 SimpleMessageListenerContainer,它将使用本机 JMS 异步侦听器。对于 IBM MQ,这是通过 MQ 回调功能实现的。这意味着侦听器将回调注册到队列管理器,队列管理器会在新消息到达队列时通知侦听器,因此没有轮询。

请参阅https://marketaylor.synology.me/?p=668

请注意,'contributions' 到 CPU 消耗 - 最终影响 MSU 费用是由几个应该控制的因素驱动的。最大的两个是:

  1. 来自 z/OS 队列管理器的连接数 to/disconnects。就 MQ 中的 CPU 使用而言,这些动词是最昂贵的,并且由于成本模型,应该在 z/OS 上明智地使用。编写一次连接并执行许多 MQ 操作的客户端应用程序将影响 CPU 消耗,但这往往是可预测的,正如他们所说 'a cost of doing business.' 连接的客户端应用程序,打开队列,发出或接收一条消息,然后多次断开连接会迅速推高成本(我们已经看到 MSU 费用在一个月内上涨 40% 的实例)。后者称为行为不佳的应用程序。
  2. 临时动态队列的使用。 TD 队列需要队列管理器内的大量开销,因为必须为每个新定义构建队列基础结构,然后在队列关闭时拆除。通过使用静态定义的队列并通过关联 ID 或消息 ID 检索消息,可以避免这种开销。 请注意,虽然这两个问题都不是 z/OS 上的 MQ 独有的,但 licensing/charging 模型才是与众不同的。
    祝你好运!