Hi xin chào mọi người!
Hiện tại em đang tìm hiểu về RabbitMQ sẵn tiện làm thử ứng dụng phổ biến nhất là gửi email dùng Spring + RabbitMQ.
Em đang bật chế độ manual cho ack khi nhận tin nhắn từ RabbitMQ ở RabbitListener
Luồng xử lý của em cơ bản là như thế này:
- Khi gửi mail thành công sẽ gọi câu lệnh basic.Ack để thông báo là nhận thành công và RMQ sẽ xóa tin nhắn đó khỏi Queue.
- Khi gửi thất bại (nhảy vào catch) thì sẽ gọi câu lệnh basic.Nack để gửi tin nhắn trở lại Queue.
Nhưng vấn đề em gặp phải là nếu gọi câu lệnh basic.Nack thì sẽ bị 1 vòng lặp vô tận => tin nhắn khi requeue xong lại nhận xong lại requeue vô tận.
Mọi người cho em hỏi là trong trường hợp của em thì nên xử lý như thế nào là ổn nhất với tin nhắn đang bị lỗi đó ạ (Tại vì nếu loop vô tận như v thì sẽ ko ổn tí nào).Có nên lưu tin nhắn ở đâu đó xong 1 khoảng thời gian sau resend 1 số lần nhất định thì có được không ạ?
Cảm ơn mọi người!
Thật tệ là ack và MQ không hay như những gì chúng ta tưởng, cụ thể là trong trường hợp gửi mail này. Rõ ràng là khi 1 mail bị gửi lỗi thì nó có thể bị lỗi vĩnh viễn và tạo ra 1 vòng lặp vô hạn nếu cố nhét mail trở lại queue.
Cách giải quyết ở đây là hãy lưu mail vào 1 bảng trong database có cấu trúc kiểu thế này: Mail(id, title, content, sendErrorCount, status, sendAt), và em có thể tạo ra 1 vòng lặp kiểu thế này:
Như vậy thì em vẫn có thể xử lý toàn bộ số mail và sẽ chặn được việc loop vô hạn thông qua maxSendErrorTimes.
Ví dụ em có 1 con service gửi Mail trong 1 hệ thống microservices.Theo em hiểu thì cái anh trả lời ở trên có phải là thêm vào mail service 1 con scheduler để chạy 1 khoảng thời gian nhất định theo định kỳ lấy những record unsent đi gửi lại phải ko ạ ?
Đúng rồi em ạ.
Anh ơi tại sao code ở trên anh lại cho Thread.Sleep vậy anh?
Làm như v có tác dụng là gì v ạ ?
Để cho CPU không bị lên 100% em ạ, giả sử không có mail nào cần gửi thì cpu cứ thực hiện vòng lặp cũng không để làm gì.
Anh cho em hỏi thêm là nếu theo như anh nói thì cái Thread.sleep nó chỉ áp dụng cho trường hơp ví dụ While(true) ở trên thôi.Còn trên thực tế khi làm email service thì scheduler ko cần dùng Thread.sleep đúng ko ạ ?
Nếu em đang dùng scheduler rồi thì không cần sleep em ạ, chỉ khi nào dùng while(true) mới cần sleep thôi