In RabbitMQ wird, wenn eine Nachricht in einer Warteschlange zu einer Dead-Letter-Nachricht (eine Nachricht, die von Verbrauchern nicht verarbeitet werden kann) wird, diese an einen anderen Austausch weitergeleitet, den wir als Dead-Letter-Austausch bezeichnen. Der Dead-Letter-Austausch leitet die Dead-Letter-Nachricht dann an eine Warteschlange weiter, die als die Dead-Letter-Warteschlange bezeichnet wird.

Veranschaulichung der Dead-Letter-Warteschlange

Dead-Letter-Warteschlange

Die obige Veranschaulichung beschreibt den gesamten Prozess von der Entstehung von Dead-Lettern bis zu deren Behandlung.

Entstehung von Dead-Lettern

Die folgenden Bedingungen führen zur Entstehung von Dead-Lettern:

  • Die Nachricht wird manuell vom Verbraucher abgelehnt (basic.reject / basic.nack) und requeue = false.
  • Die Time-to-Live (TTL) der Nachricht läuft ab.
  • Die Warteschlange erreicht maximale Länge.

Behandlungsschritte für die Dead-Letter-Warteschlange

  1. Definiere einen Dead-Letter-Austausch (lass dich nicht vom Namen täuschen, es handelt sich nur um einen regulären Austausch, er wird nur in Bezug auf die Behandlung von Dead-Lettern so genannt).
  2. Definiere eine Warteschlange, die an den Dead-Letter-Austausch gebunden ist (diese Warteschlange wird als Dead-Letter-Warteschlange bezeichnet und ist auch eine reguläre Warteschlange).
  3. Definiere einen Dead-Letter-Verbraucher, um die Dead-Letter-Warteschlange zu konsumieren (lass dich nicht vom Namen täuschen, es handelt sich ebenfalls um einen regulären Verbraucher).
  4. Binde den Dead-Letter-Austausch an die spezifische Warteschlange (die Warteschlange, die Dead-Letter behandeln muss, sollte gebunden werden).

Tipp: Siehe die obige Veranschaulichung für das Prinzip. Alle Programmiersprachen behandeln Dead-Letter-Warteschlangen auf ähnliche Weise.

Behandlung der Dead-Letter-Warteschlange in Golang

1. Definiere den Dead-Letter-Austausch

Definiere ihn wie einen regulären Austausch.

// Austausch deklarieren
err = ch.ExchangeDeclare(
    "tizi365.dead",   // Austauschname
    "topic", // Austauschtyp
    true,     // Haltbar
    false,
    false,
    false,
    nil,
)

2. Definiere die Dead-Letter-Warteschlange

Definiere sie wie eine reguläre Warteschlange.

    // Warteschlange deklarieren
    q, err := ch.QueueDeclare(
        "",    // Warteschlangenname, leer lassen, um einen zufälligen zu generieren
        false, // Haltbare Warteschlange
        false,
        true,
        false,
        nil,
    )

    // Die Warteschlange an den Dead-Letter-Austausch binden
    err = ch.QueueBind(
        q.Name, // Warteschlangenname
        "#",     // Routing-Schlüssel, # bedeutet, dass alle Routing-Schlüssel übereinstimmen, was bedeutet, dass alle Dead-Letter-Nachrichten empfangen werden
        "tizi365.dead", // Name des Dead-Letter-Austauschs
        false,
        nil)

Tipp: Behandle die Dead-Letter-Warteschlange wie eine reguläre Warteschlange.

3. Definiere den Dead-Letter-Verbraucher

// Verbraucher erstellen
msgs, err := ch.Consume(
    q.Name, // Verweis auf den zuvor genannten Dead-Letter-Warteschlangennamen
    "",     // Verbrauchername, wird nicht bereitgestellt, es wird ein zufälliger generiert
    true,   // Automatische Bestätigung der Nachrichtenverarbeitung
    false, 
    false, 
    false, 
    nil,
)

// Schleife zum Konsumieren von Nachrichten aus der Dead-Letter-Warteschlange
for d := range msgs {
    log.Printf("Dead-Letter-Nachricht empfangen=%s", d.Body)
}

4. Binde den Dead-Letter-Austausch an eine spezifische Warteschlange

	// Warteschlangeneigenschaften
	props := make(map[string]interface{})
	// Den Dead-Letter-Austausch binden
	props["x-dead-letter-exchange"] = "tizi365.dead"
	// Optional: Setze den Routing-Schlüssel, wenn der Dead-Letter an den Dead-Letter-Austausch geliefert wird. Wenn nicht festgelegt, wird der ursprüngliche Routing-Schlüssel der Nachricht verwendet.
	// props["x-dead-letter-routing-key"] = "www.tizi365.com"

	q, err := ch.QueueDeclare(
		"tizi365.demo.hello", // Warteschlangenname
		true,   // Haltbar
		false, 
		false, 
		false,   
		props,     // Warteschlangeneigenschaften festlegen
	)

Auf diese Weise werden, wenn Nachrichten in der Warteschlange tizi365.demo.hello zu Dead-Lettern werden, diese an den Dead-Letter-Austausch tizi365.dead weitergeleitet.