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:
int maxSleepTime = 100;
int maxSendErrorTimes = 3;
long nextMailId = 0;
while(true) {
long startTime = System.currentTimeMillis();
get list mail có status = UNSENT and sendErrorCount nextMailId
nếu list mail rỗng thì:
Thread.sleep(maxSleepTime)
nextMailId = 0; // xoay vòng xử lý
nếu có mail:
nextMailId = mailList.last.id
send mail
nếu send thành công thì cập nhật trạng thái status = SENT
nếu send lỗi thì tăng sendErrorCount lên 1 đơn vị và save mail
}
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 ạ ?
–
Hihi
1656594196000
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 ạ ?
–
Hihi
1656629169000
Để 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ì.
–
monkey
1656629276000
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 ạ ?
–
Hihi
1656629708000
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
–
monkey
1656629775000