En RabbitMQ, cuando un mensaje se convierte en un mensaje muerto (un mensaje que los consumidores no pueden procesar) en una cola, se reenruta a otro intercambio, al que llamamos intercambio de mensajes muertos. El intercambio de mensajes muertos luego entrega el mensaje muerto a una cola, que es la cola de mensajes muertos.
Ilustración de la cola de mensajes muertos
La ilustración anterior describe el proceso completo desde la generación de los mensajes muertos hasta su manejo.
Generación de mensajes muertos
Las siguientes son las condiciones para la generación de mensajes muertos:
- El mensaje es rechazado manualmente por el consumidor (basic.reject / basic.nack) y requeue = false.
- Expira el tiempo de vida del mensaje (TTL).
- La cola alcanza la longitud máxima.
Pasos para manejar la cola de mensajes muertos
- Definir un intercambio de mensajes muertos (no te dejes engañar por el nombre, es solo un intercambio regular, solo se llama así en el contexto del manejo de mensajes muertos).
- Definir una cola para enlazarla al intercambio de mensajes muertos (esta cola se llama cola de mensajes muertos, y también es una cola regular).
- Definir un consumidor de mensajes muertos para consumir la cola de mensajes muertos (no te dejes engañar por el nombre, también es un consumidor regular).
- Enlazar el intercambio de mensajes muertos a la cola especificada (la cola que necesita manejar los mensajes muertos debe estar enlazada).
Consejo: Consulta la ilustración anterior para entender el principio. Todos los lenguajes de programación manejan las colas de mensajes muertos de manera similar.
Manejo de la cola de mensajes muertos en Golang
1. Definir Interchange de Mensajes Muertos
Definirlo como un intercambio regular.
// Declarar el intercambio
err = ch.ExchangeDeclare(
"tizi365.dead", // Nombre del intercambio
"topic", // Tipo de intercambio
true, // Duradero
false,
false,
false,
nil,
)
2. Definir Cola de Mensajes Muertos
Definirla como una cola regular.
// Declarar la cola
q, err := ch.QueueDeclare(
"", // Nombre de la cola, dejar en blanco para generar uno al azar
false, // Cola duradera
false,
true,
false,
nil,
)
// Enlazar la cola al intercambio de mensajes muertos
err = ch.QueueBind(
q.Name, // Nombre de la cola
"#", // Clave de enrutamiento, # significa que coincide con todas las claves de enrutamiento, lo que significa recibir todos los mensajes muertos
"tizi365.dead", // Nombre del intercambio de mensajes muertos
false,
nil)
Consejo: Trata la cola de mensajes muertos como una cola regular.
3. Definir Consumidor de Mensajes Muertos
// Crear un consumidor
msgs, err := ch.Consume(
q.Name, // Hacer referencia al nombre de la cola de mensajes muertos anterior
"", // Nombre del consumidor, si no se proporciona, se generará uno al azar
true, // Confirmación automática del procesamiento del mensaje
false,
false,
false,
nil,
)
// Bucle para consumir mensajes de la cola de mensajes muertos
for d := range msgs {
log.Printf("Recibido mensaje muerto=%s", d.Body)
}
4. Enlazar el intercambio de mensajes muertos a una cola específica
// Propiedades de la cola
props := make(map[string]interface{})
// Enlazar el intercambio de mensajes muertos
props["x-dead-letter-exchange"] = "tizi365.dead"
// Opcional: Configurar la clave de enrutamiento cuando se entrega el mensaje muerto al intercambio de mensajes muertos. Si no se establece, se usará la clave de enrutamiento del mensaje original.
// props["x-dead-letter-routing-key"] = "www.tizi365.com"
q, err := ch.QueueDeclare(
"tizi365.demo.hello", // Nombre de la cola
true, // Duradero
false,
false,
false,
props, // Establecer propiedades de la cola
)
De esta manera, si los mensajes en la cola tizi365.demo.hello se convierten en mensajes muertos, serán reenviados al intercambio de mensajes muertos tizi365.dead.