问题是何时将ACK或NACK消息发送到代理。文档说:
ACK用于确认来自一个使用客户端或客户端个人确认进行订阅。任何从此类订阅收到的消息将不被视为已消耗掉,直到通过ACK确认了消息为止。
“消费”对我来说意味着“在收到并处理后”。所以我可以想象两种情况。收到消息后的情况A:
function on_message(message)
message.ack()
heavy_processing(message)
或方案B处理完消息后:
function on_message(message)
heavy_processing(message)
message.ack()
据我所知,NACK是要告诉经纪人,例如,该侦听器已被临时标记为不活动。而且,据我了解,NACK不会将由于异常而将消息标记为未处理。
因此,根据我的理解,以下伪代码将正确处理ACK / NACK和异常:
function on_message(message)
if online(): # checks resources etc
message.ack()
else:
message.nack()
return
try:
heavy_processing(message) # processing takes 5-10 minutes
catch Exception: # could be problem with this Listener or malformed message
message.put_to_dlq() # putting to dlq is a "manual" process
return
仅供参考,我正在谈论的系统是使用Stomp.py模块和ActiveMQ在Python 3.7.x中构建的。
正如您所说的,“消费”是指“在接收并处理后”,您需要在成功处理完消息后确认消息,没有任何例外。因此,[[方案B将是合适的。
来自documentationNACK与ACK相反。它用于告诉服务器客户端没有使用该消息。
因此,在这种情况下,NACK表示您已收到该消息,但未成功处理。
注意:
如果要为失败的消息维护单独的队列(导致异常的消息),则可以将这些消息发布到另一个消息(在您的情况下为dlq queue
),并向原始消息确认(ACK)为这些失败的消息排队。