La pregunta es cuándo enviar los marcos ACK o NACK al corredor. La especificación STOMP dice:

ACK se utiliza para acusar recibo del consumo de un mensaje de una suscripción utilizando el acuse de recibo del cliente o del cliente individual. Los mensajes recibidos de dicha suscripción no se considerarán consumidos hasta que el mensaje haya sido confirmado a través de un ACK.

"Consumo" significaría para mí "después de recibido y procesado". Entonces puedo imaginar dos escenarios.

Escenario A después de recibir el mensaje:

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

O Escenario B después de que se haya procesado el mensaje:

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

Como entendí, NACK es decirle al agente que este oyente, por ejemplo, ha sido marcado temporalmente como inactivo. Y como entendí también, el NACK no es para marcar un mensaje como no procesado debido a una excepción.

Entonces, el siguiente pseudocódigo manejaría ACK, NACK y las excepciones correctamente, según tengo entendido:

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

Para su información, el sistema del que estoy hablando es construir en Python 3.7.x con el módulo Stomp.py y ActiveMQ.

1
Thomas Spycher 12 feb. 2020 a las 12:11

2 respuestas

La mejor respuesta

Como dijo, "Consumo" significaría "después de recibido y procesado", debe reconocer el mensaje cuando haya procesado su mensaje con éxito sin ninguna excepción. Entonces escenario B será el adecuado.

De la documentación

NACK es lo contrario de ACK. Se utiliza para decirle al servidor que el cliente no consumió el mensaje.

Entonces NACK en este contexto significaría que ha recibido el mensaje y no lo procesó con éxito.

Nota: Si mantiene una cola separada para mensajes fallidos (los que causan Excepciones), puede publicar esos mensajes en otro (dlq queue en su caso) y reconocer positivamente (ACK) a la cola original para esos mensajes fallidos.

1
bumblebee 12 feb. 2020 a las 09:45

La especificación STOMP dice esto sobre el marco NACK:

NACK es lo opuesto a ACK. Se utiliza para decirle al servidor que el cliente no consumió el mensaje. El servidor puede enviar el mensaje a un cliente diferente, descartarlo o ponerlo en una cola de mensajes no entregados. El comportamiento exacto es específico del servidor.

Entonces, un cuadro NACK le dice al servidor que el cliente no consumió el mensaje, pero no indica por qué .

Un cuadro NACK no indica que el oyente está de alguna manera temporalmente marcado como inactivo. El agente continuará enviando mensajes al oyente (suponiendo que esté activo).

Un NACK podría indicar que el mensaje no se procesó debido a una excepción. Nuevamente, la especificación no hace una distinción entre casos aquí.

El comportamiento resultante de un NACK se deja en manos del servidor.

1
Justin Bertram 12 feb. 2020 a las 19:48