2010-09-21 17 views
12

Tengo algo así como una cola de trabajos sobre RabbitMQ y, ante la solicitud de cancelar un trabajo, me gustaría retirar las tareas que aún no han comenzado a procesarse (sus mensajes no han sido aceptados), lo que corresponde para retraer estos mensajes de las colas en las que se han enrutado.¿Cómo retractar un mensaje en RabbitMQ?

No he encontrado esta funcionalidad en AMQP o en la API RabbitMQ; quizás no he buscado lo suficientemente bien? ¿O tendré que usar una solución alternativa (no es difícil, pero aún así)?

Respuesta

2

Al menos dos maneras de lograr su objetivo:

+2

No, esto resuelve un problema diferente. No es necesario que rechace un mensaje del lado del consumidor, quiero cancelar su entrega del lado del productor, para que el mensaje no llegue a un consumidor como si nunca hubiera existido. En mi problema, un consumidor no puede decidir si un mensaje debe ser rechazado. – jkff

+4

Si los mensajes se publicaron correctamente y necesita eliminarlos de la cola conocida, suscríbase y cómprelos en el productor. –

4

RabbitMQ no le permite modificar o eliminar mensajes una vez que se han puesto en cola. Para eso, desea que algún tipo de base de datos tenga el estado de cada trabajo, y que use RabbitMQ para notificar a las partes interesadas los cambios en ese estado.

Para volúmenes reducidos, puede bloquearlo junto con una cola por trabajo. Cree la cola, publique la descripción del trabajo en la cola y anuncie el nombre de la cola a los trabajadores. Si el trabajo debe cancelarse antes de que se procese, elimine la cola del trabajo; cuando los trabajadores vienen a buscar la descripción del trabajo, notarán que la cola se ha desvanecido.

Encendedor y generalmente mejor sería usar redis u otro almacén de clave/valor para mantener el estado del trabajo (con un registro eliminado o ausente que significa un trabajo cancelado o inexistente) y usar rabbitmq para notificar sobre nuevo/eliminado/cambiado registros en el almacén de clave/valor.

1

Debe suscribirse a todas las colas a las que se enrutaron los mensajes y consumirlos con ack.

Por ejemplo, si publica en un intercambio de temas con "prueba" como la clave de enrutamiento, y hay 3 colas persistentes que se suscriben a "prueba" necesitaría consumir esas tres colas. Sería mejor agregar otra cola que sus procesos de consumidor también escucharían y decirles que ignoren esos mensajes.

Una alternativa, ya que está utilizando RabbitMQ, es escribir un plugin de intercambio personalizado que aceptará algunas instrucciones fuera de banda para borrar todas las colas. Por ejemplo, puede hacer que ese intercambio lea un encabezado de mensaje especial que le indique que borre todas las colas a las que está destinado este mensaje. Esto requiere escribir el código Erlang, pero hay 4 tipos diferentes de intercambio implementados, por lo que solo necesitarás copiar el más similar y escribir el código para los nuevos bahaviours. Si solo usa encabezados personalizados para esto, entonces el cuerpo del mensaje puede ser un mensaje normal para los consumidores.

Para resumir:

1) el editor tiene que consumir los mensajes en sí 2) el editor puede enviar un mensaje especial en una cola especial para informar a los consumidores para ignorar el mensaje 3) el editor puede enviar un mensaje especial para un intercambio personalizado que borrará todos los mensajes existentes de las colas antes de enviar este mensaje especial a los consumidores.

7

Resolvería este caso haciendo que el trabajador verifique algún tipo de fuente de datos autorizada para determinar si el trabajo debe continuar o no. Por ejemplo, el trabajador verificará el estado del trabajo en una base de datos para ver si el trabajo ya se canceló.

Para los escenarios donde la velocidad de los trabajos de procesamiento puede ser más rápida que la velocidad con la cual el almacén autorizado puede actualizarse y leerse, un almacén de datos menos garantizado que comercialice velocidad para otras características puede ser útil.

Un ejemplo de esto sería usar Redis como la tienda para cancelar el procesamiento de un mensaje en lugar de una base de datos relacional como MySQL. Redis es muy rápido, pero ofrece menos garantías con respecto a los datos que contiene, mientras que MySQL es mucho más lento, pero ofrece más garantías sobre la información que contiene.

Al final, el concepto de consultar con otra fuente para saber si procesar o no un mensaje es el mismo, pero la forma de implementarlo depende de su situación particular.