stomp.py连接Red Hat AMQ超时问题及持久化订阅咨询
问题解答
一、持久化订阅配置是否正确?
你的持久化订阅配置基本正确,满足Red Hat AMQ 7.4.1(ActiveMQ Artemis)对STOMP持久化主题订阅的核心要求:
- 连接时通过
headers={'client-id': 'testname'}指定了全局唯一的客户端标识,这是持久化订阅的基础。 - 订阅时通过
headers={"activemq.subscriptionName":"testsub"}指定了订阅名称,配合client-id可以唯一标识一个持久化订阅,服务器会为该订阅缓存未消费的消息。 subscribe方法中设置persistent=True,会向服务器发送persistent: true头,明确声明这是持久化订阅,符合Artemis的处理逻辑。
需要注意的细节:
client-id必须全局唯一,不能和其他订阅者重复,否则会导致连接冲突或订阅覆盖。activemq.subscriptionName要与client-id绑定,确保订阅的唯一性,避免不同订阅者使用相同名称导致的问题。
二、超时问题的原因与解决方法
原因
错误AMQ229014是因为服务器的连接TTL(当前为60秒)到期,期间未收到客户端的任何数据(消息或心跳),判定连接已失效并关闭。由于你的消息发布稀疏,客户端长时间处于等待状态,没有主动发送数据给服务器,触发了这个超时机制。
解决方法
通过配置STOMP心跳机制,让客户端定期向服务器发送心跳帧,保持连接活跃:
- 在创建Connection时添加心跳配置
修改连接初始化代码,设置heartbeats参数(单位:毫秒),客户端发送心跳的间隔要小于服务器的60秒TTL,建议设置为30秒:
conn = stomp.Connection(host_and_ports=[(host, port)], heartbeats=(30000, 60000))
参数说明:
- 第一个值
30000:客户端每30秒向服务器发送一次心跳帧。 - 第二个值
60000:客户端期望服务器每60秒发送一次心跳帧(如果服务器未按时发送,客户端会判定连接失效)。
stomp.py会自动在后台启动心跳线程,即使主线程处于time.sleep()等待状态,也会定期发送心跳,避免服务器触发超时关闭。
- 可选:添加重连逻辑
当服务器关闭连接后,客户端需要重新连接才能继续接收消息,可以在on_error方法中添加重连逻辑:
def on_error(self, message): print('received an error %s' % message) try: # 断开旧连接并重新连接 self.conn.disconnect() self.conn.connect(login=user, passcode=password, wait=True, headers={'client-id': 'testname'}) self.conn.subscribe(destination=destination, id=30999, ack='auto', persistent=True, headers={"activemq.subscriptionName":"testsub"}) self.stop = False # 恢复循环,继续等待消息 except Exception as e: print(f"重连失败: {e}") self.stop = True
- 不建议的方案:修改服务器TTL
虽然可以通过修改服务器的connection-ttl参数延长超时时间,但这种方式会降低服务器的故障检测能力,不如客户端发送心跳灵活,不推荐使用。
内容的提问来源于stack exchange,提问作者xymzh
相关产品推荐
相关产品推荐

