Azure 存储队列 - 将响应与请求关联起来

发布于 2025-01-05 23:49:05 字数 173 浏览 3 评论 0原文

当 Web 角色将消息放入存储队列时,它如何轮询特定的相关响应?我希望后端辅助角色将消息放置到响应队列中,其目的是调用者将拾取响应并从那里开始。

我们的目的是利用队列将一些繁重的处理任务转移到后端工作角色上,以确保 Web 角色的高性能。但是,在后端 Workers 完成并响应之前,我们不希望响应 HTTP 请求。

When a Web Role places a message onto a Storage Queue, how can it poll for a specific, correlated response? I would like the back-end Worker Role to place a message onto a response queue, with the intent being that the caller would pick the response up and go from there.

Our intent is to leverage the Queue in order to offload some heavy processing onto the back-end Worker Roles in order to ensure high performance on the Web Roles. However, we do not wish to respond to the HTTP requests until the back-end Workers are finished and have responded.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

风蛊 2025-01-12 23:49:05

我实际上正在做出类似的决定。就我而言,我有一个在 Web 角色中运行的 WCF 服务,该服务应该将计算卸载到辅助角色。计算结果后,Web 角色会将答案返回给客户端。

我的基本数据结构知识告诉我,我应该避免使用以非队列方式设计为队列的东西。这意味着队列应该始终以类似 FIFO 的方式提供服务。因此,基本上,如果对请求和响应都使用队列,则等待将数据返回给客户端的线程将不得不等待,直到计算消息位于响应队列的“顶部”,这不是最佳的。如果使用 Azure 表存储响应,线程会轮询消息,从而产生不必要的开销

我认为解决此问题的可能方法是使用请求队列。这使得能够使用竞争消费者模式,从而实现负载平衡。对于发送到此队列的消息,您可以设置 correlationId 属性 在消息上。对于回复,Azure 服务总线的发布/订阅部分(“主题”)部分与 相关过滤器。当您的后端处理完请求后,它会使用原始请求中给出的correlationId 将结果发布到“responseSubject”。现在,您的客户可以使用该相关过滤器调用 CreateSubscribtion(抱歉,我显然无法发布两个以上的链接,请通过谷歌搜索)来检索此响应,并且在发布答案时应该会收到通知。请注意,CreateSubscribtion 部分应该只在 OnStart 方法中完成一次。然后,您可以对该订阅执行异步 BeginRecieve,当其请求之一的响应可用时,该角色将在给定的回调中收到通知。 correlationId 将告诉您响应是针对哪个请求的。因此,您的最后一个挑战是将响应返回给持有客户端连接的线程。

这可以通过创建字典来实现,其中correlationId(可能是GUID)作为键,响应作为值。当您的Web角色收到请求时,它会创建guid,将其设置为correlationId,将其添加为哈希集,将消息发送到队列,然后对Guid对象调用Monitor.Wait()。然后让主题订阅调用的 receive 方法将响应添加到字典中,然后对同一 guid 对象调用 Monitor.Notify()。这会唤醒您原来的请求线程,您现在可以将答案返回给您的客户端(或者其他什么。基本上您只是希望您的线程休眠并且在等待时不消耗任何资源)

I am actually in the middle of making a similar decision. In my case i have a WCF service running in a web role which should off-load calculations to worker-roles. When the result has been computed, the web role will return the answer to the client.

My basic data structure knowledge tells me that i should avoid using something that is designed as a queue in a non-queue way. That means a queue should always be serviced in a FIFO like manner. So basically if using queues for both requests and response, the threads awaiting to return data to the client will have to wait untill the calculation message is at the "top" of the response queue, which is not optimal. If storing the responses by using Azure tables, the threads poll for messages creating unnecessary overhead

What i belive is a possible solution to this problem is using a queue for the requests. This enables use of the competeing consumers pattern and thereby load-balancing. On messages sent into this queue you set the correlationId property on the message. For reply the pub/sub part ("topics") part of Azure service bus is used togehter with a correlation filter. When your back-end has processed the request, it published a result to a "responseSubject" with the correlationId given in the original request. Now this response ca be retrieved by your client by calling CreateSubscribtion (Sorry, i can't post more than two links apparently, google it) using that correlation filter, and it should get notified when the answer is published. Notice that the CreateSubscribtion part should just be done one time in the OnStart method. Then you can do an async BeginRecieve on that subscribtion and the role will be notified in the given callback when a response for one of it's request is available. The correlationId will tell you which request the response is for. So your last challenge is giving this response back to the thread holding the client connection.

This could be achieved by creating Dictionary with the correlationId's (probably GUID's) as key and responses as value. When your web role gets a request it creates the guid, set it as correlationId, add it the hashset, fire the message to the queue and then call Monitor.Wait() on the Guid object. Then have the recieve method invoked by the topic subscribition add the response to the dictionary and then call Monitor.Notify() on that same guid object. This awakens your original request-thread and you can now return the answer to your client (Or something. Basically you just want your thread to sleep and not consume any ressources while waiting)

趁微风不噪 2025-01-12 23:49:05

Azure 服务总线上的队列具有更多功能和范例,包括发布/订阅功能,可以解决跨多个实例处理队列服务的问题。

发布/订阅的一种方法是为请求创建一个队列,为响应创建一个队列。每个请求实例还将通过标头上的过滤器订阅响应队列,以便它只会接收针对它的响应。当然,请求消息将包含放置在响应标头中以驱动过滤器的值。

The queues on the Azure Service Bus have a lot more capabilities and paradigms including pub / sub capabilities which can address issues dealing with queue servicing across multiple instance.

One approach with pub / sub, is to have one queue for requests and one for the responses. Each requesting instance would also subscribe to the response queue with a filter on the header such that it would only receive the responses targeted for it. The request message would, of course contain the value to the placed in the response header to drive the filter.

残花月 2025-01-12 23:49:05

对于基于服务总线的解决方案,有一些示例可用于使用 实现请求/响应模式队列主题(发布-订阅)

For the Service Bus based solution there are samples available for implementing Request/Response pattern with Queues and Topics (pub-sub)

不乱于心 2025-01-12 23:49:05

让工作角色不断轮询并处理消息。处理消息后,立即在表存储中添加一个条目,其中包含所需的 corelationId(RowKey) 和处理结果,然后从队列中删除已处理的消息。

然后WebRoles只需要使用所需的correlationId(RowKey) & 查找表即可。分区键

Let worker role keep polling and processing the message. As soon as the message is processed add an entry in Table storage with the required corelationId(RowKey) and the processing result, before deleting the processed message from the queue.

Then WebRoles just need to do a look up of the Table with the desired correlationId(RowKey) & PartitionKey

浪荡不羁 2025-01-12 23:49:05

看一下在辅助角色和浏览器客户端之间使用 SignalR 。因此,您的 Web 角色将一条消息放入队列并向浏览器返回结果(类似于“等待...”之类的简单内容),然后使用 SignalR 将其连接到辅助角色。这样,您的 Web 角色就可以继续执行其他操作,而不必等待异步处理的结果,只有浏览器需要这样做。

Have a look at using SignalR between the worker role and the browser client. So your web role puts a message on the queue and returns a result to the browser (something simple like 'waiting...') and hook it up to the worker role with SignalR. That way your web role carries on doing other stuff and doesn't have to wait for a result from asynchronous processing, only the browser needs to.

你的心境我的脸 2025-01-12 23:49:05

Windows Azure 队列没有任何内在的东西可以满足您的要求。但是,您可以相当轻松地自己构建它。在向队列的推送中包含消息 ID (GUID),处理完成后,让工作线程将具有该消息 ID 的新消息推送到响应通道队列中。您的 Web 应用程序可以轮询此队列以确定给定命令的处理何时完成。

我们已经做了类似的事情,并希望使用 SignalR 之类的东西来帮助在命令完成时回复客户端。

There is nothing intrinsic to Windows Azure queues that does what you are asking. However, you could build this yourself fairly easily. Include a message ID (GUID) in your push to the queue and when processing is complete, have the worker push a new message with that message ID into a response channel queue. Your web app can poll this queue to determine when processing is completed for a given command.

We have done something similar and are looking to use something like SignalR to help reply back to the client when commands are completed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文