ActiveMQ Artemis未达配置最大大小就启动分页问题排查
问题根因
- 2.17.0版本已知缺陷:该版本存在全局内存用量统计错误的BUG,运行时统计的全局内存占用值会出现异常虚高的情况,与实际内存占用完全不符。你提供的日志也可以佐证:启动日志显示全局最大内存配置为18G,但分页告警日志中
global-size-bytes仅为1,073,744,320(约1G)就触发了分页,就是统计逻辑错误导致的阈值误判。 - 地址配置匹配覆盖:如果存在优先级更高的通配符
address-setting规则(如match="#"、match="*consumer*"等),会覆盖你配置的consumer_queue精确匹配规则,导致实际生效的max-size-bytes远小于500Mb,提前触发分页。 - 内存统计包含额外开销:Artemis对地址内存的统计值不仅包含消息体本身,还包含消息元数据、内部对象引用、待持久化缓冲区等额外开销,若队列中存在大量小消息,元数据占比可超过消息体本身的30%,会出现消息体总大小远低于配置阈值但统计值达标的情况。
- 同地址多队列累加:同一个地址下如果绑定了多个队列,内存统计是该地址下所有队列的内存占用总和,而非单个队列的大小,也会出现单队列大小远低于阈值但触发分页的情况。
排查步骤
- 通过Artemis管理工具查询运行时生效配置,执行命令:
artemis address show --name consumer_queue --user <管理端用户名> --password <管理端密码>
确认实际生效的max-size-bytes、global-max-size是否符合预期。
- 检查
broker.xml中所有address-setting配置的匹配顺序,Artemis遵循最长匹配原则,确认无通配符规则覆盖consumer_queue的精确匹配。 - 开启内存统计 debug 日志,在
log4j2.properties中添加如下配置:
logger.memory.name = org.apache.activemq.artemis.core.server logger.memory.level = DEBUG logger.memory.additivity = false logger.memory.appenderRef.console.ref = CONSOLE
打印每次内存统计的计算明细,确认是否存在统计值错误累加的问题。
- 统计该地址下所有队列的消息总数、平均消息大小,计算消息体总大小,和管理端显示的地址内存占用做对比,确认是否是元数据开销导致。
修复方案
- 最彻底的方案是升级ActiveMQ Artemis到2.18.0及以上版本,该内存统计BUG在2.18.0版本已被官方修复。
- 若暂时无法升级,可手动指定固定的
global-max-size值,不要使用-1的自动适配逻辑,比如你需要18G就配置:
<global-max-size>18Gb</global-max-size>
可大幅降低统计BUG触发的概率。
- 若确认是元数据开销导致,可适当调大
max-size-bytes阈值,或者调整生产端逻辑开启消息压缩、合并小消息批量发送,降低元数据占比。 - 修正
address-setting匹配规则,将consumer_queue的精确匹配规则放在通配符规则之前,确保优先级最高不被覆盖。
内容的提问来源于stack exchange,提问作者Rony John
相关产品推荐
相关产品推荐

