Tôi có một hệ thống Java sử dụng ActiveMQ để nhắn tin. Và hệ thống xử lý khoảng 400 đến 600 giao dịch một giây và chúng tôi không gặp vấn đề gì khi mọi thứ đều hoạt động trơn tru. Hệ thống cũng phải gửi các giao dịch này đến một hệ thống bên ngoài.
Khi Hệ thống bên ngoài ngừng hoạt động trong một thời gian dài (giả sử một hoặc hai giờ), điều chúng tôi làm là chúng tôi gửi các tin nhắn thất bại không được gửi thành công đến hệ thống bên ngoài trong thời gian ngừng hoạt động cho hàng đợi (cái mà chúng tôi gọi là Hàng đợi thử lại) .
Chúng ta cần xử lý các thông điệp này một cách kịp thời để chúng ta cung cấp cho hệ thống bên ngoài đủ thời gian để phục hồi.
Chúng tôi đã thử một vài cách tiếp cận và dường như không có cách nào hoạt động hoàn hảo. Hầu hết chúng hoạt động khi chúng ta xử lý số lượng tin nhắn ít hơn.
Cách tiếp cận số 1: Chúng tôi đã sử dụng độ trễ ActiveMQ nơi chúng tôi đặt dấu thời gian trong tiêu đề JMS (Vui lòng xem tại đây để biết thêm chi tiết: http://activemq.apache.org/delay-and-schedule-message-delivery.html ) và nó hoạt động khi có hàng trăm hoặc hàng ngàn tin nhắn trong hàng đợi.
Chúng tôi thấy tin nhắn bị mất khi có khoảng 500 nghìn tin nhắn trở lên. Chúng tôi thấy rằng tin nhắn xuất hiện một cách bí ẩn mà không cho chúng tôi bất kỳ manh mối nào.
Ví dụ: tôi thấy rằng tin nhắn đã biến mất ngay cả đối với tin nhắn 20k.
Chúng tôi đặt độ trễ là 5 phút để tin nhắn được thử tối đa 12 lần trong một giờ. Khi hệ thống bên ngoài ngừng hoạt động trong một giờ, chúng tôi dự kiến rằng tất cả các tin nhắn 20k đã được thử lại ít nhất trong 12 lần.
Những gì chúng tôi quan sát được là khi chúng tôi tiêu thụ cứ sau 5 phút:
Nỗ lực 1: 20k tin nhắn Cố gắng 2: 20k tin nhắn
Cố gắng 7: 19987 tin nhắn Cố gắng 10: 19960 tin nhắn Cố gắng 12: 19957 tin nhắn
Đôi khi tất cả các tin nhắn 20k đã được xử lý nhưng kết quả kiểm tra không nhất quán.
Cách tiếp cận số 2:
Chúng tôi đã sử dụng chính sách phân phối lại của ActiveMQ nơi chúng tôi đặt chính sách ở cấp độ nhà máy kết nối, làm cho phiên giao dịch, đưa ra một ngoại lệ khi hệ thống bên ngoài ngừng hoạt động, để nhà môi giới tiếp tục gửi lại tin nhắn dựa trên cấu hình chính sách phân phối lại. Cách tiếp cận này cũng không hoạt động tốt khi mất điện kéo dài trong một thời gian dài hơn và chúng tôi không cần phải có người tiêu dùng không chặn. Nó hoạt động ở cấp độ hàng đợi công văn, làm căng hàng đợi khi có rất nhiều giao dịch đến.
Cách tiếp cận số 3:
Chúng tôi đã sử dụng bộ lập lịch Quartz thức dậy sau mỗi X phút và nó tạo ra kết nối, người tiêu dùng để nhận tin nhắn từ hàng đợi Thử lại, thử xử lý chúng thêm và nếu hệ thống bên ngoài vẫn bị hỏng, họ sẽ đưa tin nhắn thất bại vào phía sau hàng đợi. Cách tiếp cận này có rất nhiều vấn đề khiến chúng tôi buộc phải quản lý kết nối, người tiêu dùng, v.v.
Ví dụ: khi có một vài tin nhắn trong hàng đợi, khi chúng ta có nhiều người tiêu dùng hơn số lượng tin nhắn, nó đã dẫn đến một tin nhắn được người tiêu dùng chọn, một lần nữa, cùng một người tiêu dùng lại gửi tin nhắn vào Retry (như hệ thống bên ngoài vẫn không hoạt động) với một người tiêu dùng khác nhận nó, dẫn đến việc truyền đi qua lại tin nhắn giữa Người tiêu dùng và Nhà môi giới.
Cách tiếp cận số 4:
Chúng tôi đã cố gắng lưu trữ các tin nhắn thất bại trong DB và để bộ lập lịch thạch anh chạy mỗi X phút để nhận các tin nhắn từ DB.
Điều này không được tối ưu hóa cũng như liên quan đến rất nhiều kiểm tra giao dịch giữa (các) người tiêu dùng DB chạy trên nhiều nút và DB.
Môi trường của tôi là Java, JBoss, ActiveMQ 5.9, MySQL 5.6 và Spring 3.2.
Tôi đã chuyển qua một số cách tiếp cận khác như mẫu Thử lại (từ Spring) và mẫu Thử lại không đồng bộ với Java 7/8
Vấn đề của tôi là hầu hết các giải pháp đều hoạt động khi có tải tối thiểu và chúng dường như bị hỏng khi mất điện kéo dài hơn hoặc khi âm lượng tin nhắn thực sự cao.
Tôi đang tìm kiếm một cái gì đó nơi tôi có thể lưu trữ và chuyển tiếp các tin nhắn thất bại. Đối với hệ thống 400 TPS, trong một giờ, tôi có thể có 1,44 triệu tin nhắn.
Nếu Hệ thống bên ngoài không hoạt động, thì cách tôi xử lý 1,44 triệu tin nhắn này cho mỗi tin nhắn có cơ hội như nhau để được thử lại mà không làm mất tin nhắn hoặc hiệu suất.
Tôi đang tìm kiếm một giải pháp trong phạm vi môi trường tôi có.