Mat*_*att 7 performance activemq-classic jms
我正在寻找有关奇怪问题的帮助,其中队列上的慢消费者导致同一队列中的所有其他消费者以30秒的间隔开始消费消息.这是所有消费者,但速度慢的消费者并没有尽快消费消息,而是在消费之前等待一些神奇的30s屏障.
我的应用程序的基本流程如下:
我对可能导致此问题的原因感到茫然,或者如何修复它,请帮忙.
更多背景和发现
expireMessagesPeriod时间只是唤醒amq,然后它会向非慢速消费者发送消息.虽然严格来说不是问题的解决方案,但进一步的调查发现了这个问题的根本原因。
TL;DR - 这是已知行为,不会在Apollo之前修复
更多细节
最终,这是由maxPageSize属性和 AMQ 仅将选择标准应用于内存中的消息这一事实引起的。通常这些是消息选择器 ( property = value),但在我的情况下它们是JMSXGroupID=>Consumer分配。
当队列接收到消息时,它们被分页到内存中并放入一个集合中(pagedInPendingDispatch在源中命名)。为了发送消息,AMQ 将扫描这个消息列表并尝试找到一个可以接受它的消费者。这包括检查组 ID、消息选择器和预取缓冲区空间。对于我们的用例,我们不使用消息选择器,而是使用组。如果没有消费者可以接受该消息,则该消息将保留在集合中,并将在下一次滴答时再次检查。
为了阻止pagedInPendingDispatch集合耗尽所有可用资源,建议限制通过maxPageSize属性配置的此队列的大小。这个属性实际上并不是一个最大值,它更多的是暗示在正常情况下,新消息到达是应该在内存中分页还是分页到磁盘。
有了这两条信息和一个慢消费者,结果最终pagedInPendingDispatch集合中的所有消息最终只能由慢消费者使用,因此该集合被有效地阻塞,并且没有其他消息被调度。这解释了为什么慢消费者不受 30 秒间隔的影响,它已经有maxPageSize消息等待传递。
这并不能解释为什么我看到非慢速消费者每 30 秒收到一次消息。事实证明,将消息分页到内存有两种模式,正常和强制。Normal 遵循上面概述的过程,其中将集合的大小与maxPageSize属性进行比较,但是,在强制时,消息总是被分页到内存中。此模式的存在允许您浏览不在内存中的消息。碰巧这种强制模式也被过期机制使用,以允许 AMQ 使不在内存中的消息过期。
所以我们现在拥有的是内存中的一组消息,这些消息都是针对分派给同一个消费者的,消费者不会接受它们,因为它很慢或被阻塞。我们还有大量等待发送给所有消费者的消息。每expireMessagesPeriod毫秒都会有一个任务运行,强制将消息分页到内存中,以检查它们是否应该过期。这会将这些消息添加到集合中的页面上,这些页面现在包含maxPageSize发送给慢速消费者的N消息和更多发往任何消费者的消息。这些消息被传递。
QED。
参考
| 归档时间: |
|
| 查看次数: |
3342 次 |
| 最近记录: |