W RabbitMQ, gdy wiadomość staje się tzw. dead letter (wiadomość, którą konsumenci nie mogą przetworzyć) w kolejce, jest ona przekierowywana do innej wymiany, którą nazywamy wymianą dead letter. Wymiana dead letter przesyła wtedy martwą wiadomość do kolejki, którą jest kolejka dead letter.
Ilustracja kolejki dead letter
Powyższa ilustracja opisuje cały proces od generacji dead letter do ich obsługi.
Generacja Dead Letter
Poniżej znajdują się warunki generacji dead letter:
- Wiadomość jest ręcznie odrzucana przez konsumenta (basic.reject / basic.nack), a requeue = false.
- Czas życia (TTL) wiadomości wygasa.
- Kolejka osiąga maksymalną długość.
Kroki Obsługi Kolejki Dead Letter
- Zdefiniuj wymianę dead letter (nie daj się zwieść nazwie, to tylko zwykła wymiana, tak nazywa się ją tylko w kontekście obsługi dead letter).
- Zdefiniuj kolejkę do powiązania z wymianą dead letter (ta kolejka nazywana jest kolejką dead letter, to również zwykła kolejka).
- Zdefiniuj konsumenta dead letter do konsumowania kolejki dead letter (nie daj się zwieść nazwie, to również zwykły konsument).
- Powiąż wymianę dead letter z określoną kolejką (powinna być powiązana kolejka, która musi obsługiwać dead letter).
Wskazówka: Odnośnie zasady, patrz na powyższą ilustrację. Wszystkie języki programowania obsługują kolejkę dead letter w podobny sposób.
Obsługa Kolejki Dead Letter w języku Golang
1. Zdefiniuj Wymianę Dead Letter
Zdefiniuj ją jak zwykłą wymianę.
// Zadeklaruj wymianę
err = ch.ExchangeDeclare(
"tizi365.dead", // Nazwa wymiany
"topic", // Typ wymiany
true, // Trwała
false,
false,
false,
nil,
)
2. Zdefiniuj Kolejkę Dead Letter
Zdefiniuj ją jak zwykłą kolejkę.
// Zadeklaruj kolejkę
q, err := ch.QueueDeclare(
"", // Nazwa kolejki, pozostaw pustą, aby wygenerować losową
false, // Trwała kolejka
false,
true,
false,
nil,
)
// Powiąż kolejkę z wymianą dead letter
err = ch.QueueBind(
q.Name, // Nazwa kolejki
"#", // Klucz routingu, # oznacza dopasuj wszystkie klucze routingu, co oznacza odbierz wszystkie wiadomości dead letter
"tizi365.dead", // Nazwa wymiany dead letter
false,
nil)
Wskazówka: Traktuj kolejkę dead letter jak zwykłą kolejkę.
3. Zdefiniuj Konsumenta Dead Letter
// Utwórz konsumenta
msgs, err := ch.Consume(
q.Name, // Odwołaj się do wcześniejszej nazwy kolejki dead letter
"", // Nazwa konsumenta, jeśli nie podano, zostanie wygenerowana losowa
true, // Automatyczne potwierdzenie przetwarzania wiadomości
false,
false,
false,
nil,
)
// Pętla do konsumowania wiadomości z kolejki dead letter
for d := range msgs {
log.Printf("Otrzymano wiadomość dead letter=%s", d.Body)
}
4. Powiąż wymianę dead letter z określoną kolejką
// Właściwości kolejki
props := make(map[string]interface{})
// Powiąż wymianę dead letter
props["x-dead-letter-exchange"] = "tizi365.dead"
// Opcjonalnie: Ustaw klucz routingu, gdy dead letter jest dostarczany do wymiany dead letter. Jeśli nie jest ustawiony, zostanie użyty oryginalny klucz routingu wiadomości.
// props["x-dead-letter-routing-key"] = "www.tizi365.com"
q, err := ch.QueueDeclare(
"tizi365.demo.hello", // Nazwa kolejki
true, // Trwała
false,
false,
false,
props, // Ustaw właściwości kolejki
)
W ten sposób, jeśli wiadomości w kolejce tizi365.demo.hello staną się dead letter, zostaną przekierowane do wymiany dead letter tizi365.dead.