2012-02-16 28 views
8

Khi Vai trò web đặt thông báo vào Hàng đợi lưu trữ, làm cách nào để có thể thăm dò ý kiến ​​cho một phản hồi cụ thể, có liên quan? Tôi muốn Vai trò Công nhân phía sau để đặt một thông điệp lên hàng đợi phản hồi, với mục đích là người gọi sẽ chọn phản hồi và đi từ đó.Hàng đợi lưu trữ Azure - đáp ứng tương ứng với yêu cầu

Mục đích của chúng tôi là tận dụng Hàng đợi để giảm tải một số xử lý nặng lên Vai trò công nhân phía sau để đảm bảo hiệu suất cao trên Vai trò Web. Tuy nhiên, chúng tôi không muốn trả lời các yêu cầu HTTP cho đến khi các công nhân Back-end kết thúc và đã trả lời.

Trả lời

4

Tôi thực sự ở giữa đưa ra quyết định tương tự. Trong trường hợp của tôi, tôi có một dịch vụ WCF đang chạy trong một vai trò web mà nên tắt tải tính toán cho vai trò của nhân viên. Khi kết quả đã được tính toán, vai trò web sẽ trả về câu trả lời cho khách hàng.

Kiến thức cơ bản về cấu trúc dữ liệu của tôi cho tôi biết rằng tôi nên tránh sử dụng thứ gì đó được thiết kế dưới dạng hàng đợi theo cách không xếp hàng. Điều đó có nghĩa là một hàng đợi nên luôn luôn được phục vụ theo cách thức giống như FIFO. Vì vậy, về cơ bản nếu sử dụng hàng đợi cho cả hai yêu cầu và phản hồi, các luồng đang đợi trả về dữ liệu cho máy khách sẽ phải chờ cho đến khi thông báo tính toán nằm ở "hàng đầu" của hàng đợi phản hồi, không tối ưu.Nếu lưu trữ các câu trả lời bằng cách sử dụng các bảng Azure, các cuộc thăm dò chủ đề cho các thông điệp tạo chi phí không cần thiết

Điều tôi tin là một giải pháp khả thi cho vấn đề này là sử dụng hàng đợi cho các yêu cầu. Điều này cho phép sử dụng mẫu người tiêu dùng cạnh tranh và do đó cân bằng tải. Trên thư được gửi vào hàng đợi này, bạn đặt correlationId property trên thư. Để trả lời phần pub/sub ("chủ đề") của xe buýt dịch vụ Azure được sử dụng togehter với một correlation filter. Khi back-end của bạn đã xử lý yêu cầu, nó đã xuất bản kết quả cho một "responseSubject" với correlationId được đưa ra trong yêu cầu ban đầu. Bây giờ phản ứng này ca được lấy bởi khách hàng của bạn bằng cách gọi CreateSubscribtion (Xin lỗi, tôi không thể đăng nhiều hơn hai liên kết rõ ràng, google nó) bằng cách sử dụng bộ lọc tương quan đó, và nó sẽ được thông báo khi câu trả lời được xuất bản. Lưu ý rằng phần CreateSubscribtion chỉ nên được thực hiện một lần trong phương thức OnStart. Sau đó, bạn có thể làm một async BeginRecieve trên đăng ký đó và vai trò sẽ được thông báo trong cuộc gọi lại đã cho khi một phản hồi cho một trong các yêu cầu của nó có sẵn. CorrelationId sẽ cho bạn biết yêu cầu phản hồi là gì. Vì vậy, thử thách cuối cùng của bạn là đưa ra phản hồi này về chủ đề giữ kết nối máy khách.

Điều này có thể đạt được bằng cách tạo Từ điển với correlationId's (có thể là GUID) làm khóa và phản hồi dưới dạng giá trị. Khi vai trò web của bạn nhận được yêu cầu, nó tạo ra guid, đặt nó là correlationId, thêm nó vào hashset, gửi tin nhắn đến hàng đợi và sau đó gọi Monitor.Wait() trên đối tượng Guid. Sau đó, có phương thức nhận được gọi bằng cách đăng ký chủ đề thêm phản hồi vào từ điển và sau đó gọi Monitor.Notify() trên cùng một đối tượng guid đó. Điều này đánh thức yêu cầu ban đầu của bạn và bây giờ bạn có thể trả lời câu trả lời cho khách hàng của bạn (Hoặc một cái gì đó. Về cơ bản bạn chỉ muốn thread của bạn ngủ và không tiêu thụ bất kỳ tài nguyên nào trong khi chờ đợi)

1

Không có gì thực chất đối với hàng đợi Windows Azure thực hiện những gì bạn đang yêu cầu. Tuy nhiên, bạn có thể tự mình xây dựng nó khá dễ dàng. Bao gồm một tin nhắn ID (GUID) trong đẩy của bạn vào hàng đợi và khi xử lý xong, có nhân viên đẩy một tin nhắn mới với ID tin nhắn đó vào hàng đợi kênh phản hồi. Ứng dụng web của bạn có thể thăm dò ý kiến ​​hàng đợi này để xác định thời điểm xử lý được hoàn tất cho một lệnh nhất định.

Chúng tôi đã làm điều gì đó tương tự và đang tìm cách sử dụng một cái gì đó như SignalR để giúp trả lời lại cho khách hàng khi lệnh được hoàn thành.

+0

Đây là những gì tôi đã suy nghĩ. Chúng tôi đã bao gồm một chiến lược GUID Id tương quan, nhưng nó có vẻ như rất nhiều phiếu thăm dò ý kiến ​​trên hàng đợi phản hồi đó, trong đó vai trò Web kéo các câu trả lời không liên quan. Khi tôi gọi GetMessage() là có một cách để nhanh chóng phát hành nó trong các sự kiện có khả năng rằng nó không phải là phản ứng tôi đã chờ đợi? Hoặc, cách khác, có lẽ tôi có thể cung cấp cho mỗi cá thể Web Role một hàng đợi chuyên dụng. Thậm chí sau đó, những hàng đợi này không phải là FIFO, vì vậy tôi vẫn cần kiểm tra id tương quan đó. Suy nghĩ? –

+0

Bắt với điều này là nếu bạn có nhiều hơn một ví dụ của webrole (hoặc thậm chí yêu cầu khác chạy trên cùng một vai trò web), có một cơ hội rằng thông điệp dành cho ví dụ 1 sẽ nhận được bằng ví dụ 2, mà sẽ kiểm tra các tương quan id, nhận ra nó không phải chờ đợi cho nó và phải đặt nó trở lại trên hàng đợi. Tôi đã thử điều này và nó không quy mô rất tốt. Ý tưởng bàn là tốt hơn nhiều. – knightpfhor

+0

Cảm ơn bạn đã thêm nhận xét này. Tôi đã lo lắng về điều đó, xem xét rằng IIS có thể xử lý nhiều yêu cầu cùng một lúc trên cùng một hộp. –

2

Hãy để vai trò của nhân viên tiếp tục bỏ phiếu và xử lý thư. Ngay sau khi thông báo được xử lý, hãy thêm một mục trong bảng lưu trữ với corelationId được yêu cầu (RowKey) và kết quả xử lý, trước khi xóa thông báo đã xử lý khỏi hàng đợi.

Sau đó WebRoles chỉ cần làm một cái nhìn lên của Bảng với mong muốn correlationId (RowKey) & PartitionKey

+0

Ý tưởng rất hay. Tôi thích điều này phù hợp, bởi vì chỉ có Vai trò Web khởi xướng yêu cầu cần xem phản hồi. Tôi sẽ cần một số loại bộ thu gom rác cho các mục lưu trữ Bảng mồ côi mà không bao giờ bị xuất hiện trong trường hợp lỗi Web Role. –

+0

Tôi không nghĩ đây là một ý hay. Sau đó, bạn về cơ bản xây dựng một hệ thống xếp hàng mới (sử dụng lưu trữ bảng) thay vì sử dụng các tính năng hàng đợi/chủ đề dành riêng trong Azure. Ngoài ra, bạn sẽ phải thăm dò bảng lưu trữ cho phản hồi = rất kém hiệu quả và không thể mở rộng. – Haukman

3

Các hàng đợi trên xe buýt Dịch vụ Azure có rất nhiều khả năng và mô hình bao gồm pub/sub khả năng có thể giải quyết các vấn đề liên quan đến việc xử lý hàng đợi trong nhiều trường hợp.

Một cách tiếp cận với pub/sub, là có một hàng đợi cho các yêu cầu và một cho các câu trả lời. Mỗi cá thể yêu cầu cũng sẽ đăng ký hàng đợi phản hồi với một bộ lọc trên tiêu đề sao cho nó sẽ chỉ nhận các câu trả lời được nhắm mục tiêu cho nó. Tất nhiên, thông báo yêu cầu sẽ chứa giá trị được đặt trong tiêu đề phản hồi để điều khiển bộ lọc.

+0

Chào mừng bạn đến với stackoverflow.Tôi đánh giá cao phản ứng của bạn và tôi sẽ xem tùy chọn Dịch vụ xe buýt. Tôi nhận thấy rằng các câu trả lời khác của bạn liên quan đến Azure. Tôi hy vọng sẽ đọc nhiều như họ! –

+0

Cảm ơn sự chào đón nồng hậu. Tôi hy vọng sẽ đóng góp nhiều hơn nữa. Vâng, kinh nghiệm hiện tại của tôi tất cả đều có liên quan. – hocho

2

Hãy xem sử dụng SignalR giữa vai trò của người lao động và trình duyệt của khách hàng. Vì vậy, vai trò web của bạn đặt một thông điệp trên hàng đợi và trả về kết quả cho trình duyệt (một cái gì đó đơn giản như 'chờ đợi ...') và móc nó lên vai trò công nhân với SignalR. Bằng cách đó, vai trò web của bạn thực hiện trên các công cụ khác và không phải đợi kết quả từ việc xử lý không đồng bộ, chỉ cần trình duyệt cần.

3

Đối với các giải pháp dựa trên dịch vụ xe buýt có mẫu sẵn để thực hiện các mô hình request/response với QueuesTopics (pub-sub)

+0

Cảm ơn bạn. Liệu nó có một cơ sở để đảm bảo rằng, trong khi phản ứng dành cho các thuê bao, phản ứng thực sự là tương quan với yêu cầu ban đầu? –

+1

Cũng giống như một Hàng đợi đơn giản cho phép bạn cạnh tranh cho Tin nhắn, một Hàng đợi Dịch vụ đã bật Phiên cho phép bạn cạnh tranh cho Phiên. Ở đây bạn có thể chỉ định SessionId và sau đó Khóa phiên đó. Bất kỳ thư nào được gửi đến Phiên đó sẽ chỉ được gửi cho bạn. Vì vậy, nếu mỗi người đăng ký có Id duy nhất của họ mà họ sử dụng làm SessionID và sau đó gửi cùng với các thông báo như ReplyToSessionId, mã duy nhất cần thiết để đảm bảo phản hồi tương quan là đối với thông điệp Trả lời chúng tôi đã đặt: ReplyMessage.SessionId = RequestMessage. ReplyToSessionId. Mẫu này được thể hiện trong các mẫu. –

+1

Cảm ơn bạn đã trả lời. Tôi đã bình chọn cho bạn. Tôi đã chọn câu trả lời từ [@Henrikmh] (http://stackoverflow.com/users/859401/henrikmh) vì đoạn cuối về việc sử dụng Từ điển làm cơ chế tương quan. Chúng tôi sẽ có nhiều yêu cầu đồng thời từ cùng một máy chủ. Phiên giải quyết vấn đề đăng ký cho máy chủ đã cho, nhưng không giải quyết được yêu cầu đồng thời. Tôi tin rằng bạn có thể đã để lại điều đó như một bài tập cho người đọc. :-) –

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