首页 文章

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

提问于
浏览
8

当Web角色将消息放入存储队列时,如何轮询特定的相关响应?我希望后端的Worker Role将消息放到响应队列中,目的是让调用者选择响应并从那里开始 .

我们的目的是利用Queue将一些繁重的处理卸载到后端的Worker Roles上,以确保Web角色的高性能 . 但是,在后端Worker完成并做出响应之前,我们不希望响应HTTP请求 .

6 回答

  • 3

    我实际上正在做出类似的决定 . 在我的情况下,我有一个在Web角色中运行的WCF服务,该服务应该将计算卸载到worker-roles . 计算结果后,Web角色将向客户端返回答案 .

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

    我所相信的是这个问题的一个可能的解决方案是使用队列来处理请求 . 这使得能够使用竞争的消费者模式,从而实现负载 balancer . 在发送到此队列的消息中,您可以在消息上设置correlationId property . 对于回复,Azure服务总线的pub / sub部分("topics")部分用于correlation filter . 当您的后端处理了请求时,它会将结果发布到"responseSubject",其中包含原始请求中的correlationId . 现在,您的客户可以通过调用CreateSubscribtion来检索此响应(对不起,我可以'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'的请求可用.relationId将告诉您响应的请求 . 所以您的最后一个挑战是将此响应返回给持有客户端的线程连接 .

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

  • 3

    Azure Service Bus 上的队列具有更多功能和范例,包括 pub / sub 功能,可以解决跨多个实例处理队列服务的问题 .

    pub / sub的一种方法是为请求设置一个队列,为响应设置一个队列 . 每个请求实例还将订阅响应队列,并在标头上使用过滤器,以便它只接收针对它的响应 . 当然,请求消息将包含放置在响应头中的值以驱动过滤器 .

  • 1

    对于基于Service Bus的解决方案,可以使用QueuesTopics (pub-sub)实现请求/响应模式的示例

  • 2

    让worker角色继续轮询和处理消息 . 处理完消息后,在从队列中删除已处理消息之前,在表存储中添加具有所需corelationId(RowKey)和处理结果的条目 .

    然后WebRoles只需要查看具有所需correlationId(RowKey)和PartitionKey的表

  • 2

    看看在worker角色和浏览器客户端之间使用SignalR . 因此,您的Web角色会在队列中放置一条消息并将结果返回给浏览器(类似于'waiting...'这样的简单事件)并将其与SignalR挂钩到worker角色 . 这样你的web角色就可以继续做其他事情而不必等待异步处理的结果,只需要浏览器需要 .

  • 4

    Windows Azure队列没有任何内在功能可以满足您的要求 . 但是,你可以很容易地自己构建它 . 在推送到队列中包含消息ID(GUID),并且在处理完成时,让工作人员将具有该消息ID的新消息推送到响应通道队列中 . 您的Web应用程序可以轮询此队列以确定何时完成给定命令的处理 .

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

相关问题