【问题标题】:What does a high Spring JMS DefaultMessageListenerContainer.receiveTimeout parameter mean?高 Spring JMS DefaultMessageListenerContainer.receiveTimeout 参数是什么意思?
【发布时间】:2016-12-09 08:55:41
【问题描述】:

我正在进入一个实现 IBM MQ 侦听 Spring JMS 应用程序的项目,但我无法理解 DefaultMessageListenerContainer 中的“receiveTimeout”。

与来自互联网的资源相比,我认为我的项目有点特别,我们为“receiveTimeout”参数使用了一个非常高的 30 秒值,我不知道这实际上意味着什么。

我已经尝试弄清楚“receiveTimeout”参数的含义,在Spring配置之后我将在下面给你我的理解。

仅供参考:我们正在从一个队列中读取/处理许多非常小的消息(大约 100kb)。

这是我们正在使用的弹簧配置:

<bean id="msgListenerContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer"
        p:connectionFactory-ref="mqConnectionFactory" 
        p:messageListener-ref="myMessageListener" p:sessionTransacted="true"
        p:concurrentConsumers="1" p:maxConcurrentConsumers="20"
        p:receiveTimeout="30000" p:idleTaskExecutionLimit="10"
        p:idleConsumerLimit="5" />

如果有人想知道这里的不同参数是我在互联网上收集的:

idleConsumerLimit 属性用于指定最大值 在给定时间允许空闲的消费者数量。 增加此限制会导致更积极地创建调用程序。 这对于更快地增加消费者数量很有用。

idleTaskExecutionLimit:允许的空闲次数限制 接收任务的执行。默认为 1 导致资源空闲 一旦任务没有收到消息就提前关闭。 idleTaskExecutionLimit 属性设置为 10 以允许任务执行 10 次,而不是默认值 1。

receiveTimeout 属性设置为 30 秒以告知 DMLC 接收操作轮询消息 30 秒,而不是 默认一秒。

这是我的理解:

所以这意味着:如果负载很重,Spring JMS 最多会启动 20 消费者(maxConcurrentConsumers),一旦负载下降,这些消费者将 在关闭或空闲之前继续阅读消息 30 秒 (receiveTimeout)。 所以在那之后5个消费者(idleConsumerLimit)仍然会空闲10秒(?)(idleTaskExecutionLimit)之前 倒闭。

如果我错了,请纠正我。

一个网页说我的消费者每 30 秒只会阅读一条消息,但我认为这不是对“receiveTimeout”的正确解释。

我们目前遇到的一个问题是,我们从 MQ 读取了很多 GET,但实际上并没有收到消息 - 就像我们可以有 60'000 个 GET 实际能够读取消息,而 2'100'000 GET 发生但没有读取消息。

感谢任何帮助我更好地理解 Spring JMS 的行为。

【问题讨论】:

    标签: spring-jms


    【解决方案1】:

    在询问代理客户端是否还有更多工作时使用接收超时 (receive()) - 它不是轮询代理,只是轮询客户端库以查看代理是否发送了更多消息。它与接收消息的频率无关。

    当超时发生时,容器立即再次调用receive()

    接收超时时间长意味着容器对stop() 调用的响应会降低 - 容器只能在receive() 调用之间停止。

    【讨论】:

    • 在这 30 秒内容器实际调用 'receive()' 方法的频率是多少?容器何时调用 'stop()' 方法?在 30 秒后和以下 'receive()' 之后,如果队列中没有消息?
    • 容器线程在其处于活动状态时会不断调用消费者的 receive() 方法(它会阻塞 30 秒)。容器不调用stop() - 你可以调用它,但它只能在“接收”之间生效。因此它会以更短的时间更快地停止。
    • 啊,我明白了。如果您主动调用stop(),在实际调用之前仍然需要这 30 秒——参考receiveTimeout 参数。谢谢!再说一遍,这在我的应用程序中并不重要,因为我们从不调用 stop() 方法。我也觉得我无法更改框架调用receive() 方法的间隔。我不确定我描述的这个问题是否真的是一个问题,或者只是框架的正常行为,因为我缺乏经验(有 2'100'000 条消息,而只收到 60'000 条消息)
    • @GaryRussell 我必须每“n”秒阅读“n”条消息。示例:我需要每秒接收 10 条消息。这可以通过将 receiveTimeout 设置为 1000 毫秒并将 maxConcurrentConsumers 设置为 10 来实现吗?
    • 不要在 cmets 中针对 5 年前的答案提出新问题。您的用例不清楚。提出一个更详细的新问题。
    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 2013-07-07
    • 2016-10-17
    • 2015-03-05
    • 2014-05-31
    • 2012-09-16
    • 2020-12-16
    • 2017-04-13
    相关资源
    最近更新 更多