Apache Artemis跨版本联邦环境消费大消息遇NegativeArraySizeException
问题描述
使用ActiveMQ Artemis Core Jakarta Messaging 2.37.0消费消息时,抛出NegativeArraySizeException,控制台标记该消息为大消息,无法直接获取负载。环境包含3个运行2.36.0版本的broker节点,客户端使用2.37.0版本。消息在节点间流转,消息数波动,消费者持续收到消息但无法读取,且消息不会进入死信队列(DLQ)。需要解决如何恢复或检查消息负载的问题。
错误堆栈
2025-04-22 17:31:50.545 WARN [topic#eu.JmsListenerAnnotationBeanPostProcessor#1-12] - (eu.JmsListenerAnnotationBeanPostProcessor$1$1:1092) - Setup of JMS message listener invoker failed for destination 'example.user.v1.roles' - trying to recover. Cause: -1663738403 java.lang.NegativeArraySizeException: -1663738403 at org.apache.activemq.artemis.api.core.SimpleString.readSimpleString(SimpleString.java:257) ~[artemis-commons-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.api.core.SimpleString.readSimpleString(SimpleString.java:243) ~[artemis-commons-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.api.core.SimpleString.readNullableSimpleString(SimpleString.java:230) ~[artemis-commons-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.core.buffers.impl.ChannelBufferWrapper.readNullableSimpleString(ChannelBufferWrapper.java:79) ~[artemis-commons-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.reader.TextMessageUtil.readBodyText(TextMessageUtil.java:37) ~[artemis-core-client-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.jms.client.ActiveMQTextMessage.doBeforeReceive(ActiveMQTextMessage.java:106) ~[artemis-jakarta-client-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer.getMessage(ActiveMQMessageConsumer.java:230) ~[artemis-jakarta-client-2.37.0.jar:2.37.0] at org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:134) ~[artemis-jakarta-client-2.37.0.jar:2.37.0] at org.springframework.jms.support.destination.JmsDestinationAccessor.receiveFromConsumer(JmsDestinationAccessor.java:132) ~[spring-jms-6.2.1.jar:6.2.1] at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:441) ~[spring-jms-6.2.1.jar:6.2.1]
更新记录
更新1 - 2025/04/29
切换到2.36.0版本后问题依旧,执行artemis browser命令报错:
$ artemis browser --user artemis --password artemis --url 'tcp://messaging-01.dc.eu:61616?sslEnabled=true' --destination domain-events.#::audit-trail_shared Connection brokerURL = tcp://messaging-01.dc.eu:61616?sslEnabled=true Consumer:: filter = null Consumer ActiveMQQueue[domain-events.#::audit-trail_shared], thread=0 trying to browse 1000 messages 2025-04-29 10:54:07,448 ERROR [org.apache.activemq.artemis.jms.client] AMQ134002: Queue Browser failed to create message ClientLargeMessageImpl[messageID=956935038, durable=true, address=domain-events.global.customer-service.v1.customers,userID=63df8053-20d5-11f0-84de-9a2c728d6a7d,properties=TypedProperties[ResourceType=CUSTOMER, EventVersion=v1, _AMQ_Hops=[0000 0001], Address=domain-events.global.customer-service.v1.customers, Authorization={"jwtPrincipal":{"tokenValue":"eyJhbGQy...c53835cbd"}},"authorities":[]}, _AMQ_ROUTING_TYPE=0, AuthorizationType=jwt-v1.0, _AMQ_LARGE_COMPRESSED=false, OperationType=CREATE, EventDateTime=2025-04-24T06:28:52.318060801Z, _AMQ_LARGE_SIZE=130153, __AMQ_CID=63d7b820-20d5-11f0-84de-9a2c728d6a7d, SendOffsetDateTime=2025-04-24T06:28:52.318060801Z, timestamp=1745476132318]] java.lang.NegativeArraySizeException: -1662157365 at org.apache.activemq.artemis.api.core.SimpleString.readSimpleString(SimpleString.java:257) ~[artemis-commons-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.api.core.SimpleString.readSimpleString(SimpleString.java:243) ~[artemis-commons-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.api.core.SimpleString.readNullableSimpleString(SimpleString.java:230) ~[artemis-commons-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.core.buffers.impl.ChannelBufferWrapper.readNullableSimpleString(ChannelBufferWrapper.java:79) ~[artemis-commons-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.reader.TextMessageUtil.readBodyText(TextMessageUtil.java:37) ~[artemis-core-client-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.jms.client.ActiveMQTextMessage.doBeforeReceive(ActiveMQTextMessage.java:106) ~[artemis-jms-client-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.jms.client.ActiveMQQueueBrowser$BrowserEnumeration.nextElement(ActiveMQQueueBrowser.java:139) [artemis-jms-client-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.jms.client.ActiveMQQueueBrowser$BrowserEnumeration.nextElement(ActiveMQQueueBrowser.java:110) [artemis-jms-client-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.cli.commands.messages.ConsumerThread.browse(ConsumerThread.java:127) [artemis-cli-2.36.0.jar:2.36.0] at org.apache.activemq.artemis.cli.commands.messages.ConsumerThread.run(ConsumerThread.java:69) [artemis-cli-2.36.0.jar:2.36.0] Consumer ActiveMQQueue[domain-events.#::audit-trail_shared], thread=0 browsed: 0 messages Consumer ActiveMQQueue[domain-events.#::audit-trail_shared], thread=0 Browser thread finished
更新2 - 2025/05/02
生产者始终通过URL配置:61616?compressLargeMessages=true启用压缩发送消息。手动解压/data/large-message文件夹中的消息负载:
cat 872923939.msg | python3 -c "import sys, zlib; print(zlib.decompress(sys.stdin.buffer.read()).decode('latin'))"
输出开头有两个意外字符(如½¬),怀疑影响客户端解压。近期将Artemis客户端版本从2.31.x升级到2.37.x。
更新3 - 2025/05/28
发现消息在federation-A生产,流转到federation-B后,federation-B的消费者接收时触发异常。federation-A的broker.xml配置:
<connectors> <connector name="artemis">tcp://qa-messaging-01.example.com:61616</connector> <connector name="cloud-01-connector">tcp://qa-messaging-federation-01.example.com:61616?sslEnabled=true;ackBatchSize=100;consumerWindowSize=-1</connector> <connector name="clous-02-connector">tcp://qa-messaging-federation-02.example.com:61616?sslEnabled=true;ackBatchSize=100;consumerWindowSize=-1</connector> <connector name="cloud-03-connector">tcp://qa-messaging-federation-03.example.com:61616?sslEnabled=true;ackBatchSize=100;consumerWindowSize=-1</connector> </connectors>
<federations> <federation name="federation-A" user="federation-user" password="******"> <upstream name="cloud-qa"> <static-connectors> <connector-ref>cloud-01-connector</connector-ref> <connector-ref>cloud-02-connector</connector-ref> <connector-ref>cloud-03-connector</connector-ref> </static-connectors> <policy ref="domain-events-federation"/> </upstream> <address-policy name="domain-events-federation" max-hops="1" auto-delete="false"> <include address-match="domain-events.example.#"/> </address-policy> </federation> </federations>
解决方案建议
1. 修复消息负载的异常前缀
手动处理大消息文件,去掉开头的两个意外字符后重新解压,确认消息内容是否完整:
cat 872923939.msg | tail -c +3 | python3 -c "import sys, zlib; print(zlib.decompress(sys.stdin.buffer.read()).decode('utf-8'))"
如果内容正常,说明消息在传输或存储过程中被额外写入了前缀字节,导致客户端解析时错误计算数组大小。
2. 统一客户端与Broker版本
将Broker版本升级到2.37.0,保持客户端与Broker版本一致,验证是否因版本差异导致压缩逻辑不兼容。
3. 调整联邦连接器的压缩配置
在federation-A的连接器配置中添加compressLargeMessages=true,确保联邦转发时保持压缩状态,避免消息负载被篡改:
<connector name="cloud-01-connector">tcp://qa-messaging-federation-01.example.com:61616?sslEnabled=true;ackBatchSize=100;consumerWindowSize=-1;compressLargeMessages=true</connector>
同时检查federation-B的Broker是否启用压缩支持,确保两端配置一致。
4. 删除损坏消息
若消息无法修复,可通过Artemis CLI删除指定消息:
artemis queue remove --user artemis --password artemis --url 'tcp://messaging-01.dc.eu:61616?sslEnabled=true' --queue domain-events.#::audit-trail_shared --message-id 956935038
或清空整个队列(需确认数据可丢弃):
artemis queue purge --user artemis --password artemis --url 'tcp://messaging-01.dc.eu:61616?sslEnabled=true' --queue domain-events.#::audit-trail_shared
5. 启用大消息校验
在Broker的broker.xml中添加大消息校验配置,拦截损坏消息:
<large-messages-directory>data/large-messages</large-messages-directory> <max-large-message-size>104857600</max-large-message-size> <enable-large-messages>true</enable-large-messages> <validate-large-messages>true</validate-large-messages>
内容的提问来源于stack exchange,提问作者André Conrado

