提问者:小点点

何时在STOMP中的队列侦听器上发送确认字符或NACK


问题是何时向代理发送确认字符NACK帧。STOMP规范说:

确认字符用于使用客户端或客户端个体确认确认确认订阅消息的消费。在此类订阅中收到的任何消息在通过确认字符确认消息之前都不会被视为已消费。

“消费”对我来说意味着“接收和处理后”。所以我可以想象两种情况。

场景A收到消息后:

function on_message(message)
    message.ack()
    heavy_processing(message)

或消息处理后的场景B:

function on_message(message)
    heavy_processing(message)
    message.ack()

根据我的理解,NACK是告诉代理,例如,这个侦听器被临时标记为非活动的。正如我所理解的,NACK不是因为异常而将消息标记为未处理。

因此,根据我的理解,以下伪代码将正确处理确认字符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

FYI我所说的系统是在Python3.7. x中构建的,带有Stomp.py模块和ActiveMQ。


共2个答案

匿名用户

正如您所说,“消费”意味着“收到并处理后”,当您成功处理消息时,您需要无一例外地确认消息。所以场景B将是合适的。

从留档

NACK与确认字符相反。它用于告诉服务器客户端没有使用该消息。

因此,在这种情况下NACK意味着您已收到消息,但未成功处理它。

注意:如果您为失败的消息(导致异常的消息)维护一个单独的队列,那么您可以将这些消息发布到另一个(在您的情况下为dlq队列)并积极确认(确认字符)这些失败消息的原始队列。

匿名用户

STOMP规范是这样描述NACK框架的:

NACK确认字符相反。它用于告诉服务器客户端没有使用该消息。然后,服务器可以将消息发送到不同的客户端,丢弃它,或者将其放入死信队列中。确切的行为是特定于服务器的。

因此,一个NACK帧告诉服务器客户端没有使用该消息,但它没有说明原因。

NACK帧并不表示监听器以某种方式暂时标记为不活动。代理将继续向监听器发送消息(假设它是活动的)。

NACK可以表示由于异常而未处理消息。同样,规范在这里没有区分情况。

NACK产生的行为由服务器决定。