检测并删除Azure Service Bus上的孤立队列,主题或订阅

时间:2012-09-08 22:03:10

标签: azure appfabric servicebus azure-appfabric

如果没有任何发布者或订阅者读取或写入队列,主题或订阅,由于崩溃或其他异常终止(实例重启等),队列/主题/订阅是否有效孤立?< / p>

我通过创建一些队列来测试它,然后终止应用程序。这些队列很久以后仍然在服务总线上。似乎他们将永远呆在那里。如果我们想要这种行为,那将是美妙的,但在这种情况下,我们不会。

我们如何检测和删除这些队列,主题和订阅?它们将计入Azure限制等,每次重新启动/修补/崩溃时,我们都不能拥有这些孤立的进程。

如果它有助于使问题更加清晰,则这是一种独特的情况,其中队列/主题/订阅具有特殊名称或特殊过滤器,以及一组非常有限的发布者(1)和订阅者(1)限时。这不是我们想要生存的情况。这些是特定于实例的响应通道。我们是否使用队列或订阅是无关紧要的。如果实例消失了,那么对该队列(或订阅)的需求也是如此。

这是解决方案的一部分,其中每个Web角色都有一个监控的专用响应通道。在任何时候,此Web角色可能有许多通过其他消息传递通道(队列/主题)挂起的请求,并且它正在等待多个线程上的答案。我们需要响应返回放置消息的线程,以便Web角色可以响应调用者。在这种情况下,简单地使用基于机器的订阅是不好的,因为它将接收其他线程的消息。我们需要每个发布线程建立一个专用的响应通道,以便该通道上唯一的东西就是该线程的响应。

即使我们使用Subscriptions(使用某种与实例相关的过滤器)对Subscription进行长轮询接收操作,如果Web角色实例死亡,该Subscription将被孤立,是否正确?

这个问题可以像这样简化: 如果队列/主题/订阅中没有其他发布者或订阅者,则该服务实际上是孤立的。如何检测和清理这些孤儿?

5 个答案:

答案 0 :(得分:2)

在这种情况下,您正在寻找队列/订阅本质上是“动态的”。它们将基于使用而创建和删除,而不是针对这些实体的当前显式供应模型。 Service Bus为您提供了执行创建/删除操作的API,因此您可以适当地在OnStart / OnStop角色事件上插入这些操作。如果这些操作由于某种原因失败,那么孤立的实体将存在。您可以再次根据实体名称的唯一标识符对它们运行清理操作。这方面的一个例子可以在这里看到:http://windowsazurecat.com/2011/08/how-to-simplify-scale-inter-role-communication-using-windows-azure-service-bus/

在不久的将来,我们将为队列/主题/订阅添加更多元数据和查询功能,以便您可以查看上次访问它们的时间并做出清理决策。

答案 1 :(得分:1)

服务总线队列使用“代理消息传递”基础结构构建,该基础结构旨在集成可能跨越多个通信协议,数据协定,信任域和/或网络环境的应用程序或应用程序组件。允许机制与持久消息传递可靠地通信。

如果客户端(发布者)向服务总线队列发送消息然后崩溃,则消息将存储在队列中,直到消费者从队列中读取消息为止。此外,如果您的消费者死亡并重新启动它将只轮询队列并获取正在等待它的任何工作(您可以向外扩展并让多个消费者从队列中读取以提高吞吐量),Service Bus Queues允许您通过队列解耦您的应用程序耐用的云网关,类似于MSMQ内部部署(或其他排队技术)。

我真正想说的是你没有获得孤立的队列,你可能会收到需要处理的中毒消息,这篇博文提供了一些非常详细的信息:服务总线队列及其容量和配额可能会让您更好地理解http://msdn.microsoft.com/en-us/library/windowsazure/hh767287.aspx

Re:队列管理,您可以通过Visual Studio(1.7 SDK和工具)执行此操作,或者有一个名为Service Bus Explorer的优秀工具,可以让您的队列管理生活更轻松:http://code.msdn.microsoft.com/windowsazure/Service-Bus-Explorer-f2abca5a

*请注意,默认的最大队列数为10,000(每个服务命名空间,可通过支持呼叫增加)

答案 2 :(得分:1)

正如Abhishek Lai所说,没有支持孤儿检测能力。

孤儿检测可以通过多种方式在外部实施。 例如,无论何时发送/接收消息,都要更新SQL数据库中的时间戳,以指示queue / tropic / subscription仍处于活动状态。然后可以使用此时间戳确定孤儿。

答案 3 :(得分:0)

如果您的进程很可能崩溃,那么队列中的邮件传递就会出现问题,但队列仍然可用于处理您的请求。使用Windows Azure Service Bus处理应用程序崩溃和不可读消息的行为是here

Service Bus提供的功能可帮助您优雅地从应用程序中的错误中恢复,或者难以处理消息。如果接收器应用程序由于某种原因无法处理消息,则它可以在接收的消息上调用Abandon方法(而不是Complete方法)。这将导致服务总线解锁队列中的消息,并使其可供同一消费应用程序或其他消费应用程序再次接收。

如果应用程序在处理完消息之后但在发出完成请求之前崩溃,则在重新启动时将重新传送消息给应用程序。这通常称为至少一次处理,即,每个消息将被处理至少一次,但在某些情况下,可以重新传送相同的消息。如果方案不能容忍重复处理,那么应用程序开发人员应该向其应用程序添加其他逻辑以处理重复的消息传递。这通常使用消息的MessageId属性来实现,该属性在传递尝试中保持不变。

答案 4 :(得分:0)

  

如果没有任何进程读取或写入队列,由于崩溃或其他异常终止(实例重启等),该队列是否有效孤立?

没有队列允许通过Brokered Messages进行通信,如果所有应用程序因某种原因而死亡,那么队列仍然存在并且当它们再次变为活动时将存在,它是松散分离的应用程序的通信通道。问候结算'消息是根据在结算月期间发送到服务总线或由服务总线发送的消息数量收费的'如果队列存在但没有人使用它,则不会向您收费。

  

我通过创建几个队列来测试它,然后终止   应用。那些队列还在机器上很久了   后面。

队列的重点是保证松散分离的应用程序的消息传递。将队列视为一个实体或应用程序本身具有高可用性(SLA)作为其托管在Azure中,您的生产者/消费者可以死/重新启动并且队列将在Azure中处于活动状态。 *注意我对你的措辞有点困惑:“很长一段时间后仍然在机器上”,队列实际上不在您的机器上,它在Azure中位于指定的服务总线命名空间中。您可以通过我在上一个答案中指出的工具查看和管理队列。

  

我们如何检测和删除这些队列,因为他们会计入   Azure限制等。

如上所述,默认的最大队列数是10,000(每个服务命名空间,这可以通过支持调用增加),队列管理可以通过另一个答案中陈述的工具完成。当您不再有生产者/消费者想要写入队列时(或从不再次),您应该只想删除队列。您当然可以通过namespaceManager.QueueExists在生产者/消费者应用程序中创建和删除队列,更多信息请参见How to Use Service Bus Queues

  

如果它有助于使问题更清晰,这是一种独特的情况,其中队列具有特殊名称,并且在有限时间内有非常有限的发布者(1)和订阅者(​​1)。

听起来你需要使用话题&amp;订阅How to Use Service Bus Topics/Subscriptions,此链接还有一个关于“如何删除主题和订阅”的部分如果您的生命周期非常有限,那么您可以在应用中处理主题创建/删除,否则您可能会有一个单独的队列/主题/订阅设置/删除脚本来处理这个逻辑...