2011-11-28 34 views
8

Tôi làm việc trên ứng dụng web là ứng dụng dựa trên đám mây nhiều người thuê (nhiều khách hàng, mỗi khách hàng có "môi trường" riêng biệt, nhưng tất cả trên bộ phần cứng được chia sẻ) và chúng tôi đang giới thiệu khả năng người dùng thực hiện hàng loạt công việc để xử lý sau này. Các loại công việc theo lô thực sự không quan trọng, nó chỉ đủ số lượng mà làm việc đó mà không có hàng đợi công việc không thực sự thực tế. Chúng tôi đã chọn RabbitMQ làm khung xếp hàng cơ bản của chúng tôi. Vì chúng tôi là một ứng dụng đa người thuê nhà, chúng tôi không nhất thiết muốn khách hàng có thể gây ra thời gian xử lý hàng đợi dài cho một khách hàng khác, do đó, một ý tưởng mà chúng tôi đã nổi lên là tạo hàng đợi trên mỗi cơ sở khách hàng và có một nhóm công nhân được chia sẻ chỉ trên tất cả các hàng đợi của khách hàng của chúng tôi. Vấn đề là, theo điều tốt nhất mà tôi có thể hình dung, người lao động trực tiếp bị ràng buộc vào một hàng đợi cụ thể, không phải là một sự trao đổi. Trong thế giới lý tưởng của chúng tôi, hàng đợi của khách hàng của chúng tôi sẽ vẫn được xử lý, mà không có khách hàng nào chặn khác, từ một nhóm công nhân được chia sẻ mà chúng tôi có thể tăng hoặc thu hẹp khi cần thiết bằng cách khởi chạy nhiều công nhân hơn hoặc đóng cửa không hoạt động. Có công nhân gắn với một hàng đợi cụ thể ngăn cản chúng tôi từ này trong một ý nghĩa thực tế, như chúng tôi thường xuyên có rất nhiều công nhân chỉ chạy không tải trên một hàng đợi không có hoạt động.Hàng công nhân và hàng đợi nhiều người thuê nhà với RabbitMQ

Có tương đối thẳng về phía trước để thực hiện việc này không? Tôi khá mới với RabbitMQ và không thực sự có thể đạt được những gì chúng tôi đang theo đuổi. Chúng tôi cũng không muốn phải viết một ứng dụng người dùng đa luồng rất phức tạp, đó là thời gian chìm trong thời gian thử nghiệm và dev mà chúng tôi có thể không đủ khả năng. Ngăn xếp của chúng tôi là Windows/.Net/C# dựa trên nếu đó là germaine, nhưng tôi không nghĩ rằng cần phải có một mang lớn trong câu hỏi trong tầm tay.

Trả lời

1

Bạn chỉ có thể có nhóm công nhân của mình đều sử dụng cùng một hàng đợi duy nhất. Công việc sau đó sẽ được phân phối trên chúng và bạn sẽ có thể phát triển/thu hẹp hồ bơi của bạn để tăng/giảm khả năng xử lý công việc của bạn.

+1

Tôi không hỏi về việc gán nhiều công nhân cho cùng một hàng đợi, tôi sắp hỏi về điều ngược lại. Tôi muốn một nhóm công nhân hữu hạn tiêu thụ từ một lượng lớn (chúng ta hãy gọi nó là ~ 500) số hàng đợi. – bakasan

+1

Tôi đã thử nghiệm trực tiếp với kiểu tiếp cận này và nó không đẹp: thật khó để tìm ra một heuristic phù hợp để xử lý tất cả các hàng đợi này. Bạn có xử lý trước hàng đợi đầy đủ nhất không? Hoặc những người có tin nhắn cũ hơn? Trong cả hai trường hợp, bạn đã ra khỏi giao thức AMQP và phải bắt đầu giao dịch với API quản lý Rabbit. Sau đó, bạn nghĩ: chúng ta hãy có cùng số hàng đợi hơn so với công nhân và bạn thêm một số ánh xạ băm nhất quán giữa 500 Q và hàng đợi công nhân. Sau đó, bạn nhận ra rằng một hàng đợi và n công nhân cạnh tranh trên đó là tất cả những gì bạn cần. –

+0

Tôi có một yêu cầu tương tự, tuy nhiên tôi muốn đảm bảo thông điệp từ một khách hàng cụ thể được xử lý tuần tự. Một số liên lạc không bị xóa trước khi nó được tạo ra vv Có một số cấu hình hoặc thiết lập của RabbitMQ có thể làm điều này chưa chia sẻ hàng đợi giữa các công nhân? (Đây có phải là một Q mới ...?) – Aaron

1

Tôi không hiểu tại sao bạn không sử dụng vhost của RabbitMQ và đăng nhập ứng dụng của bạn lên RabbitMQ và xác thực trên kết nối riêng cho từng người dùng.

Điều này không có nghĩa là bạn không thể có người giám sát công nhân giao công nhân cho người dùng này hoặc người dùng khác. Nhưng nó có nghĩa là tất cả các tin nhắn cho mỗi người dùng được xử lý bằng cách trao đổi hoàn toàn riêng biệt và hàng đợi.

0

Công nhân được chỉ định 0 hàng đợi, chứ không phải trao đổi.

Logic mà nhiệm vụ sẽ được thực hiện từ hàng đợi nào cho mỗi công nhân được thực hiện trong lớp được chỉ ra qua CELERYD_CONSUMER, theo mặc định là celery.worker.consumer.Consumer.

Bạn có thể tạo một lớp người tiêu dùng tùy chỉnh ro thực hiện bất kỳ logic nào bạn thích. Phần cứng sẽ quyết định chi tiết thuật toán "công bằng" mà bạn muốn sử dụng; nhưng một khi bạn đã quyết định rằng, bạn có thể thực hiện nó được tạo ra một lớp tiêu dùng tùy chỉnh và gán nó cho những người lao động thích hợp.

1

Bạn có thể nhìn vào việc thực hiện hàng đợi ưu tiên (mà đã không được thực hiện khi câu hỏi này được hỏi ban đầu): https://www.rabbitmq.com/priority.html

Nếu điều đó không làm việc cho bạn, bạn có thể thử một số hack khác để đạt được những gì bạn muốn (nên làm việc với các phiên bản cũ của RabbitMQ):

Bạn có thể có 100 hàng đợi bị ràng buộc đối với trao đổi chủ đề và đặt khóa định tuyến thành mã băm của ID người dùng% 100, tức là mỗi tác vụ sẽ có khóa giữa 1 và 100 và nhiệm vụ cho cùng một người dùng sẽ có cùng một khóa. Mỗi hàng đợi được gắn với một mẫu duy nhất từ ​​1 đến 100.Bây giờ bạn có một đội ngũ công nhân bắt đầu với số hàng đợi ngẫu nhiên và sau đó tăng số hàng đợi đó sau mỗi công việc, một lần nữa% 100 để quay trở lại hàng đợi 1 sau hàng đợi 100.

Bây giờ đội ngũ nhân viên của bạn có thể xử lý lên tới 100 người dùng duy nhất song song hoặc tất cả người lao động có thể tập trung vào một người dùng nếu không có công việc nào khác để làm. Nếu người lao động cần phải xoay vòng tất cả 100 hàng đợi giữa mỗi công việc, trong trường hợp chỉ có một người dùng có nhiều công việc trên một hàng đợi, bạn sẽ tự nhiên có một số chi phí giữa mỗi công việc. Số lượng hàng đợi nhỏ hơn là một cách để giải quyết vấn đề này. Bạn cũng có thể có mỗi nhân viên giữ một kết nối với mỗi hàng đợi và tiêu thụ tối đa một tin nhắn chưa được xác nhận từ mỗi người. Sau đó, nhân viên có thể chuyển qua các thư đang chờ xử lý trong bộ nhớ nhanh hơn nhiều, miễn là thời gian chờ của thông báo chưa được xác nhận được đặt đủ cao.

Hoặc bạn có thể tạo hai trao đổi, mỗi trao đổi có hàng đợi bị ràng buộc. Tất cả các công việc đi đến trao đổi và xếp hàng đầu tiên, mà một nhóm công nhân tiêu thụ. Nếu một đơn vị công việc mất quá lâu, nhân viên có thể hủy bỏ nó và đẩy nó vào hàng đợi thứ hai. Công nhân chỉ xử lý hàng đợi thứ hai khi không có gì trên hàng đợi đầu tiên. Bạn cũng có thể muốn một vài công nhân có thứ tự ưu tiên đối diện để đảm bảo rằng các tác vụ chạy dài vẫn được xử lý khi có một luồng công việc ngắn không bao giờ kết thúc, do đó, một nhóm người dùng sẽ luôn được xử lý cuối cùng. Điều này sẽ không thực sự phân phối đội ngũ công nhân của bạn trên tất cả các nhiệm vụ, nhưng nó sẽ ngăn chặn các nhiệm vụ chạy dài từ một người dùng đang giữ công nhân của bạn thực hiện các tác vụ chạy ngắn cho cùng người dùng đó hoặc người khác. Nó cũng giả định bạn có thể hủy bỏ một công việc và chạy lại nó sau này mà không có bất kỳ vấn đề gì. Nó cũng có nghĩa là sẽ có nguồn tài nguyên bị lãng phí từ các nhiệm vụ hết thời gian chờ và cần phải được chạy lại dưới dạng ưu tiên thấp. Trừ khi bạn có thể xác định các tác vụ nhanh và chậm trước

Đề xuất đầu tiên với 100 hàng đợi cũng có thể có vấn đề nếu có 100 tác vụ chậm cho một người dùng, sau đó người dùng khác đăng một loạt tác vụ. Những nhiệm vụ đó sẽ không được xem xét cho đến khi một trong các nhiệm vụ chậm được hoàn thành. Nếu điều này hóa ra là một vấn đề hợp pháp, bạn có khả năng kết hợp hai giải pháp.

Các vấn đề liên quan