5

如果由于崩溃或其他异常终止(实例重启等)而不再有任何发布者或订阅者读取或写入队列、主题或订阅,那么该队列/主题/订阅是否有效地孤立了?

我通过创建几个队列来测试这一点,然后终止应用程序。很长一段时间后,这些队列仍在服务总线上。似乎他们将永远呆在那里。如果我们想要这种行为,那就太好了,但在这种情况下,我们不需要。

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

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

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

即使我们使用 Subscriptions(带有某种与实例相关的过滤器)对 Subscription 进行长轮询接收操作,如果 Web 角色实例死亡,该 Subscription 也会成为孤儿,对吗?

这个问题可以归结为:如果队列/主题/订阅不再有发布者或订阅者,那么该服务实际上是孤立的。如何检测和清理这些孤儿?

4

5 回答 5

3

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

在不久的将来,我们将向 Queues/Topics/Subscriptions 添加更多元数据和查询功能,以便您可以查看上次访问它们的时间并做出清理决策。

于 2012-09-11T21:55:07.997 回答
1

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

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

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

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

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

于 2012-09-09T01:00:34.560 回答
1

正如 Abhishek Lai 提到的,不支持孤儿检测功能。

孤儿检测可以通过多种方式在外部实现。例如,每当您发送/接收消息时,更新 SQL 数据库中的时间戳以指示队列/热带/订阅仍处于活动状态。然后可以使用此时间戳来确定孤儿。

于 2012-09-11T22:26:41.800 回答
0

如果您的进程很可能会崩溃,那么队列中的消息传递将会出现问题,但是队列仍可用于处理您的请求。此处描述了使用 Windows Azure 服务总线队列处理应用程序崩溃和不可读消息:

服务总线提供的功能可帮助您从应用程序中的错误或处理消息的困难中正常恢复。如果接收方应用程序由于某种原因无法处理消息,那么它可以对收到的消息调用 Abandon 方法(而不是 Complete 方法)。这将导致服务总线解锁队列中的消息,并使其可以再次被同一个消费应用程序或另一个消费应用程序接收。

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

于 2012-09-09T01:13:18.513 回答
0

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

没有队列允许通过代理消息进行通信,如果您的所有应用程序由于某种原因死亡,那么队列仍然存在并且当它们再次活跃时将在那里,它是松散解耦应用程序的通信通道。关于计费 “消息根据在计费月份发送到服务总线或由服务总线传递的消息数量收费”,如果存在队列但没有人使用它,则不会向您收费。

我通过创建几个队列然后终止应用程序对此进行了测试。很长一段时间后,这些队列仍在机器上。

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

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

如上所述,默认的最大队列数为 10,000(每个服务命名空间,这可以通过支持呼叫增加),队列管理可以通过另一个答案中所述的工具来完成。只有当您不再有生产者/消费者希望写入队列时(即再也不会),您才应该考虑删除队列。您当然可以通过 namespaceManager.QueueExists 在您的生产者/消费者应用程序中创建和删除队列,更多信息在这里如何使用服务总线队列

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

听起来您需要使用主题和订阅如何使用服务总线主题/订阅,此链接还有一个关于“如何删除主题和订阅”的部分如果您的生命周期非常有限,那么您可以在你的应用程序,否则你可以有一个单独的队列/主题/订阅设置/删除脚本来处理这个逻辑......

于 2012-09-09T20:14:13.870 回答