You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python通过STOMP向ActiveMQ Artemis发消息时JMSMessageID缺失问题

问题:Python STOMP发送消息到ActiveMQ Artemis导致Spring JMS抛出NoJMSMessageIdException

我用Python通过STOMP协议向ActiveMQ Artemis队列发送消息,Spring JMS应用接收时抛出异常:

NoJMSMessageIdException: MISSING_JMS_MESSAGE_ID.

我尝试设置JMSMessageID、msgID、MESSAGE_ID等多种消息头或属性,甚至按文档要求添加ID:前缀,但都没解决问题。我的应用通过javax.jms.Message.getJMSMessageID()方法验证消息,请问这个方法期望的JMSMessageID格式是什么?如何在Python STOMP客户端正确设置并发送?

Python STOMP客户端文档只提供发送示例,未说明如何设置JMSMessageID,发送方法定义如下:

Protocol12.send(destination, body, content_type=None, headers=None, **keyword_headers)
向消息系统的目标发送消息(遵循STOMP 1.2规范)
参数:

  • destination (str) – 消息目标(如队列'/queue/test'或主题)
  • body: 消息内容
  • content_type (str): 消息MIME类型
  • headers (dict): 消息帧中的额外头信息
  • keyword_headers: 代理要求的其他额外头信息

我的代码如下:

import stomp
import json

jsonRequest = {
    "data": {
        "key": "value"
    }
}

class MyListener(stomp.ConnectionListener):
    def on_error(self, frame):
        print('received an error "%s"' % frame.body)

    def on_message(self, frame):
        print('received a message "%s"' % frame.body)

conn = stomp.Connection([('host', 63001)])
conn.set_listener('', MyListener())
conn.connect('user', 'password', wait=True)
conn.subscribe(destination='queue', id=1, ack='auto')
conn.send(destination='queue', body=json.dumps(jsonRequest),  
          MESSAGE_ID='e5bf8c3d-0dc4-11ed-a28a-544d36153f8c', 
          JMSMessageID='ID:e5bf8c3d-0dc4-11ed-a28a-544d36153f5c', 
          headers={'MESSAGE_ID': 'ID:e5bf8c3d-0dc4-11ed-a28a-544d36153f5c', 
                   'JMSCorrelationID': '123278256677', 
                   'JMSReplyTo': 'queue'},
          MSGUID="3e4fb627-85df-4b37-b37b-1070c7893c99", 
          TotalNumberMsg=1, 
          CurrentNumberMsg=1, 
          UIPSYSTEMDATA=72)

test = MyListener()

后端服务错误日志:

2022-07-27 20:10:53 [,] [DefaultMessageListenerContainer-2] ERROR service.jms.listener.base.AbstractArtemisMessageListener - Exception while processing message MISSING_JMS_MESSAGE_ID
service.exception.NoJMSMessageIdException: MISSING_JMS_MESSAGE_ID

用JMS ToolBox发送的消息有正确ID:

2022-07-27 18:58:03 [,] [DefaultMessageListenerContainer-2] INFO  service.jms.listener.base.AbstractArtemisMessageListener - Message from srv: ActiveMQMessage[ID:e5bf8c3d-0dc4-11ed-a28a-544d36153f0c]:PERSISTENT/ClientLargeMessageImpl[messageID=318412845, durable=true, address=queue,userID=e5bf8c3d-0dc4-11ed-a28a-544d36153f0c,properties=TypedProperties[__AMQ_CID=JMSToolBox-1657948224556,TotalNumberMsg=1,JMSReplyTo=queue://,_AMQ_ROUTING_TYPE=1,MSGUID=3e4fb627-85df-4b37-b37b-1070c7893c82,SERVICENAME=service,JMSCorrelationID=5515D5431364567,_AMQ_VALIDATED_USER=ACTIVEMQ.CLUSTER.ADMIN.USER,CurrentNumberMsg=1,UIPSYSTEMDATA=063224508,_AMQ_LARGE_SIZE=308737]] with correlationId: 5515D5431364567

而STOMP发送的消息中JMSMessageID为NULL:

2022-07-27 19:12:52 [,] [DefaultMessageListenerContainer-2] INFO  service.jms.listener.base.AbstractArtemisMessageListener - Message from srv: ActiveMQMessage[null]:NON-PERSISTENT/ClientLargeMessageImpl[messageID=318581407, durable=false, address=queue,userID=null,properties=TypedProperties[content-length=110919,destination=queue,JMSReplyTo=queue,TotalNumberMsg=1,_AMQ_ROUTING_TYPE=1,MSGUID=3e4fb627-85df-4b37-b37b-1070c7893c99,SERVICENAME=service,JMSCorrelationID=123278256677,_AMQ_VALIDATED_USER=ACTIVEMQ.CLUSTER.ADMIN.USER,CurrentNumberMsg=1,UIPSYSTEMDATA=72,_AMQ_LARGE_SIZE=110919,messageID=125774553292,JMSType=NULL-value]] with correlationId: 123278256677

解决方案

1. JMSMessageID的标准格式

javax.jms.Message.getJMSMessageID()要求的格式是ID:<唯一标识符>,其中唯一标识符通常是UUID或类似的全局唯一字符串(比如日志里的ID:e5bf8c3d-0dc4-11ed-a28a-544d36153f0c)。这个格式是JMS规范定义的,代理会将符合该格式的头映射到JMSMessageID字段。

2. Python STOMP客户端的正确设置方法

ActiveMQ Artemis对于STOMP协议的消息,需要通过特定的STOMP头来传递JMSMessageID,而不是直接用JMSMessageID作为头名。正确的头是AMQ_JMS_MESSAGE_ID,需要将值设置为ID:<UUID>格式。

另外需要注意:

  • STOMP头名是大小写敏感的,必须严格使用AMQ_JMS_MESSAGE_ID
  • 消息要设置为持久化(添加persistent='true'头),否则代理可能不会正确处理JMS属性映射

3. 修正后的代码示例

import stomp
import json
import uuid

jsonRequest = {
    "data": {
        "key": "value"
    }
}

class MyListener(stomp.ConnectionListener):
    def on_error(self, frame):
        print('received an error "%s"' % frame.body)

    def on_message(self, frame):
        print('received a message "%s"' % frame.body)

# 生成符合格式的JMSMessageID
message_id = f"ID:{uuid.uuid1()}"

conn = stomp.Connection([('host', 63001)])
conn.set_listener('', MyListener())
conn.connect('user', 'password', wait=True)
conn.subscribe(destination='queue', id=1, ack='auto')

# 正确设置头信息
conn.send(
    destination='queue',
    body=json.dumps(jsonRequest),
    headers={
        'AMQ_JMS_MESSAGE_ID': message_id,
        'JMSCorrelationID': '123278256677',
        'JMSReplyTo': 'queue',
        'persistent': 'true'  # 持久化消息,确保JMS属性被正确处理
    },
    MSGUID="3e4fb627-85df-4b37-b37b-1070c7893c99",
    TotalNumberMsg=1,
    CurrentNumberMsg=1,
    UIPSYSTEMDATA=72
)

test = MyListener()

4. 验证逻辑

发送后查看后端日志,若消息日志显示ActiveMQMessage[ID:xxx]而非null,则说明JMSMessageID设置成功,NoJMSMessageIdException会被解决。


内容的提问来源于stack exchange,提问作者EvgeniY S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:15:30