Trong RabbitMQ, khi một tin nhắn trở thành tin nhắn đầu cuối (một tin nhắn mà người tiêu thụ không thể xử lý) trong hàng đợi, nó sẽ được định tuyến đến một sàn giao dịch khác, mà chúng ta gọi là sàn giao dịch đầu cuối. Sàn giao dịch đầu cuối sau đó chuyển giao tin nhắn đầu cuối đến một hàng đợi, đó chính là hàng đợi đầu cuối.
Minh họa Hàng đợi Đầu cuối
Hình minh họa trên mô tả toàn bộ quá trình từ việc tạo ra các tin nhắn đầu cuối đến việc xử lý chúng.
Tạo ra các tin nhắn đầu cuối
Dưới đây là các điều kiện để tạo ra các tin nhắn đầu cuối:
- Tin nhắn bị từ chối thủ công bởi người tiêu thụ (basic.reject / basic.nack), và requeue = false.
- Thời gian sống của tin nhắn (TTL) hết hạn.
- Hàng đợi đạt đến độ dài tối đa.
Bước xử lý Hàng đợi Đầu cuối
- Định nghĩa một sàn giao dịch đầu cuối (đừng bị lầm bởi tên, đó chỉ là một sàn giao dịch thông thường, chỉ được gọi như vậy trong ngữ cảnh xử lý đầu cuối).
- Định nghĩa một hàng đợi để ràng buộc với sàn giao dịch đầu cuối (hàng đợi này được gọi là hàng đợi đầu cuối, và cũng là một hàng đợi thông thường).
- Định nghĩa một người tiêu thụ đầu cuối để tiêu thụ hàng đợi đầu cuối (đừng bị lầm bởi tên, đó cũng là một người tiêu thụ thông thường).
- Ràng buộc sàn giao dịch đầu cuối với hàng đợi cụ thể (hàng đợi cần xử lý các tin nhắn đầu cuối sẽ được ràng buộc).
Mẹo: Tham khảo hình minh họa phía trên để hiểu nguyên lý. Tất cả các ngôn ngữ lập trình đều xử lý hàng đợi đầu cuối một cách tương tự.
Xử lý Hàng đợi Đầu cuối trong Golang
1. Định nghĩa Sàn Giao Dịch Đầu Cuối
Định nghĩa nó như một sàn giao dịch thông thường.
// Khai báo sàn giao dịch
err = ch.ExchangeDeclare(
"tizi365.dead", // Tên sàn giao dịch
"topic", // Loại sàn giao dịch
true, // Bền vững
false,
false,
false,
nil,
)
2. Định nghĩa Hàng đợi Đầu Cuối
Định nghĩa nó như một hàng đợi thông thường.
// Khai báo hàng đợi
q, err := ch.QueueDeclare(
"", // Tên hàng đợi, để trống để tạo ra một cái ngẫu nhiên
false, // Hàng đợi bền vững
false,
true,
false,
nil,
)
// Ràng buộc hàng đợi với sàn giao dịch đầu cuối
err = ch.QueueBind(
q.Name, // Tên hàng đợi
"#", // Khóa định tuyến, # có nghĩa là phù hợp với tất cả các khóa định tuyến, có nghĩa là nhận tất cả các tin nhắn đầu cuối
"tizi365.dead", // Tên sàn giao dịch đầu cuối
false,
nil)
Mẹo: Xem xử lý hàng đợi đầu cuối như một hàng đợi thông thường.
3. Định nghĩa Người Tiêu Thụ Đầu Cuối
// Tạo một người tiêu thụ
msgs, err := ch.Consume(
q.Name, // Tham chiếu đến tên hàng đợi đầu cuối ở trên
"", // Tên người tiêu thụ, nếu không cung cấp, một người tiêu thụ ngẫu nhiên sẽ được tạo
true, // Tự động xác nhận việc xử lý tin nhắn
false,
false,
false,
nil,
)
// Vòng lặp để tiêu thụ các tin nhắn từ hàng đợi đầu cuối
for d := range msgs {
log.Printf("Nhận tin nhắn đầu cuối=%s", d.Body)
}
4. Ràng buộc Sàn Giao Dịch Đầu Cuối với một Hàng đợi Cụ thể
// Thuộc tính hàng đợi
props := make(map[string]interface{})
// Ràng buộc sàn giao dịch đầu cuối
props["x-dead-letter-exchange"] = "tizi365.dead"
// Tùy chọn: Đặt khóa định tuyến khi tin nhắn đầu cuối được chuyển giao đến sàn giao dịch đầu cuối. Nếu không đặt, khóa định tuyến ban đầu của tin nhắn sẽ được sử dụng.
// props["x-dead-letter-routing-key"] = "www.tizi365.com"
q, err := ch.QueueDeclare(
"tizi365.demo.hello", // Tên hàng đợi
true, // Bền vững
false,
false,
false,
props, // Đặt thuộc tính hàng đợi
)
Như vậy, nếu các tin nhắn trong hàng đợi tizi365.demo.hello trở thành các tin nhắn đầu cuối, chúng sẽ được chuyển tiếp đến sàn giao dịch đầu cuối tizi365.dead.