Thiết kế thử lại cho khối lượng lớn


8

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ó.

Câu trả lời:


1

Vấn đề ở đây là với điều tiết. Khi hệ thống xuất hiện, ứng dụng cần được thiết kế sao cho không bị quá tải đối với cả nhà xuất bản và người tiêu dùng.

Bạn có thể có được thông minh với thuật toán của bạn. Nếu bạn có khả năng phân loại tin nhắn theo mức độ ưu tiên thì các tin nhắn thất bại có thể được lưu với mức độ ưu tiên thấp hơn. Vì vậy, sau khi nhà xuất bản xuất bản một tin nhắn mới, nó có thể xem xét hàng đợi ưu tiên thấp hơn để kiểm tra xem có bất kỳ tin nhắn thất bại nào cần tái xuất bản và tái xuất bản chúng hay không.

Đây là một cách tiếp cận nổi tiếng đối với các thông điệp điều chỉnh. Tôi chắc chắn có các thuật toán điều chỉnh khác có thể được áp dụng ở đây dựa trên nhu cầu cụ thể của bạn.


0

Đây là giả định mỗi nút có một hàng đợi tin nhắn và tất cả các nút này đang sử dụng một DB. Tất cả các nút này đang cố gắng gửi tin nhắn đến một hệ thống bên ngoài.

Một thay đổi nhỏ trong cách tiếp cận thứ ba có thể làm việc.

  1. Khi một nút bắt đầu tạo một bảng để chỉ lưu trữ các tin nhắn mới trong trường hợp hệ thống bên ngoài bị hỏng. Hãy nói rằng nút1 đã tạo bảng Messages_node1 để lưu trữ các tin nhắn.

Bây giờ trường hợp sử dụng là nếu 3 nút đang chạy tất cả hệ thống bên ngoài đột ngột ngừng hoạt động, thì mỗi nút sẽ lưu trữ các tin nhắn mới đến vào bảng tương ứng thay vì xếp hàng trong MQ.Keep các tin nhắn chưa được gửi trong hàng đợi. Hệ thống bên ngoài cần khôi phục, hàng đợi nhắn tin hiện tại sẽ không được tải. Một khi nút nhận ra rằng hệ thống bên ngoài đã hoạt động, sau đó bắt đầu xếp hàng tin nhắn từ bảng tương ứng.

Cách tiếp cận này giải quyết nhiều vấn đề 1. Nó không phụ thuộc vào thời gian phục hồi của hệ thống bên ngoài 2. Nó không bị sập trong trường hợp có quá nhiều tin nhắn đến trong khi hệ thống bên ngoài bị hỏng. 3. Liên kết giữa các nút được giảm thiểu vì mỗi nút có bảng riêng. 4.Thông tin của các tin nhắn được bảo tồn ở một mức độ nào đó.

Bạn có thể viết API để kích hoạt các sự kiện này. Bất kỳ sửa chữa với cách trả lời trên

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.