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
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
- 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).
- 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).
- 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).
- 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.