No RabbitMQ, quando uma mensagem se torna uma mensagem inválida (ou seja, uma mensagem que os consumidores não conseguem processar) em uma fila, ela é reencaminhada para outra exchange, que chamamos de exchange de mensagens inválidas. A exchange de mensagens inválidas então entrega a mensagem inválida para uma fila, que é a fila de mensagens inválidas.

Ilustração da Fila de Mensagens Inválidas

Fila de Mensagens Inválidas

A ilustração acima descreve todo o processo, desde a geração das mensagens inválidas até o seu tratamento.

Geração de Mensagens Inválidas

As seguintes são as condições para a geração de mensagens inválidas:

  • A mensagem é manualmente rejeitada pelo consumidor (basic.reject / basic.nack), e requeue = false.
  • O tempo de vida útil da mensagem (TTL) expira.
  • A fila atinge o comprimento máximo.

Etapas de Tratamento da Fila de Mensagens Inválidas

  1. Definir uma exchange de mensagens inválidas (não se deixe enganar pelo nome, é apenas uma exchange regular, é apenas chamada assim no contexto do tratamento de mensagens inválidas).
  2. Definir uma fila para se ligar à exchange de mensagens inválidas (esta fila é chamada fila de mensagens inválidas, e também é uma fila regular).
  3. Definir um consumidor de mensagens inválidas para consumir a fila de mensagens inválidas (não se deixe enganar pelo nome, também é um consumidor regular).
  4. Vincular a exchange de mensagens inválidas à fila especificada (a fila que precisa lidar com mensagens inválidas deve ser vinculada).

Dica: Consulte a ilustração acima para entender o princípio. Todas as linguagens de programação lidam com filas de mensagens inválidas de maneira semelhante.

Tratando a Fila de Mensagens Inválidas em Golang

1. Definir Exchange de Mensagens Inválidas

Defina como uma exchange regular.

// Declarar a exchange
err = ch.ExchangeDeclare(
    "tizi365.dead",   // Nome da exchange
    "topic", // Tipo de exchange
    true,     // Durável
    false,
    false,
    false,
    nil,
)

2. Definir Fila de Mensagens Inválidas

Defina como uma fila regular.

    // Declarar a fila
    q, err := ch.QueueDeclare(
        "",    // Nome da fila, deixe em branco para gerar um aleatório
        false, // Fila durável
        false,
        true,
        false,
        nil,
    )

    // Vincular a fila à exchange de mensagens inválidas
    err = ch.QueueBind(
        q.Name, // Nome da fila
        "#",     // Chave de roteamento, # significa corresponder a todas as chaves de roteamento, ou seja, receber todas as mensagens inválidas
        "tizi365.dead", // Nome da exchange de mensagens inválidas
        false,
        nil)

Dica: Trate a fila de mensagens inválidas como uma fila regular.

3. Definir Consumidor de Mensagens Inválidas

// Criar um consumidor
msgs, err := ch.Consume(
    q.Name, // Referenciar o nome da fila de mensagens inválidas anterior
    "",     // Nome do consumidor, se não fornecido, um será gerado aleatoriamente
    true,   // Confirmação automática do processamento da mensagem
    false, 
    false, 
    false, 
    nil,
)

// Loop para consumir mensagens da fila de mensagens inválidas
for d := range msgs {
    log.Printf("Recebeu mensagem inválida=%s", d.Body)
}

4. Vincular a Exchange de Mensagens Inválidas a uma Fila Específica

	// Propriedades da fila
	props := make(map[string]interface{})
	// Vincular a exchange de mensagens inválidas
	props["x-dead-letter-exchange"] = "tizi365.dead"
	// Opcional: definir a chave de roteamento quando a mensagem inválida for entregue à exchange de mensagens inválidas. Se não for definida, a chave de roteamento da mensagem original será usada.
	// props["x-dead-letter-routing-key"] = "www.tizi365.com"

	q, err := ch.QueueDeclare(
		"tizi365.demo.hello", // Nome da fila
		true,   // Durável
		false, 
		false, 
		false,   
		props,     // Definir propriedades da fila
	)

Desta forma, se as mensagens na fila tizi365.demo.hello se tornarem mensagens inválidas, elas serão encaminhadas para a exchange de mensagens inválidas tizi365.dead.