异步消息传送模式和高可用性

可以通过多种不同的方式实现异步消息传送。 使用队列、主题和订阅,Azure Service Bus通过存储转发机制支持异步通信。 在正常(同步)操作中,会将消息发送到队列和主题,并从队列和订阅接收消息。 编写的应用程序依赖于这些始终可用的实体。 当实体运行状况因各种环境而发生变化时,需要一种能够提供满足大多数需求的缩减功能实体的方式。

应用程序通常使用异步消息传送模式来实现大量通信方案。 可以构建一些应用程序,以便客户端在其中可以向服务发送消息(即使该服务未运行)。 对于将经历大量通信的应用程序,队列可以通过提供缓冲通信的场所,帮助对负载进行分级。 最后,可以获得一个简单而高效的负载均衡器,从而在多台计算机间分发消息。

有关异步可伸缩性和预期延迟或重试的实际类比,请参阅 Gregor Hohpe 的 星巴克不使用两阶段提交 ,以及后续的 星巴克能教会我们关于软件可伸缩性的内容。 他们为Service Bus在负载下的行为提供了明确的心理模型。

为了维护这些实体的可用性,需要考虑它们在持久消息系统中可能出现不可用的不同情境。 一般来说,我们发现所编写的应用程序中的实体在以下几种情况下不可用:

  • 无法发送消息。
  • 无法接收消息。
  • 无法管理实体(创建、检索、更新或删除实体)。
  • 无法与服务取得联系。

对于以上每种故障,存在不同的故障模式,从而使应用程序能够在某种程度功能缩减的情况下继续执行工作。 例如,可以发送消息但无法接收消息的系统仍可以从客户接收指令,但无法处理这些指令。 本主题讨论了可能发生的潜在问题,以及如何缓解这些问题。 Service Bus引入了许多必须选择加入的缓解措施,本主题还讨论了有关使用这些选择加入缓解措施的规则。

注意

若要了解 Service Bus 如何具备应对一系列问题的恢复能力,以及可以使用的提高其可靠性的能力,请参阅 Azure Service Bus 中的可靠性。

失败模式类型

可通过多种方式来处理消息和实体问题,有一套对这些缓解措施的恰当使用进行管理的准则。 若要了解这些准则,必须先了解Service Bus中的可能失败点。 由于Azure系统的设计,所有这些问题往往短期存在。 从高层次来看,不可用性的各种原因如下所示:

  • 受Service Bus依赖的外部系统的限制。 与存储和计算资源的交互会导致限流。
  • Service Bus所依赖的系统的问题。 例如,存储的给定部分可能遇到问题。
  • 单个子系统上的Service Bus失败。 在这种情况下,计算节点可能会陷入不一致状态并必须重新启动,从而导致其服务的所有实体转移负载至其他节点。 这又可能导致短时间内消息处理变慢。
  • Azure数据中心内的Service Bus故障。 这是“灾难性故障”,无论故障时间是数分钟还是几小时,在此期间都无法访问系统。

注意

术语 storage可以同时表示Azure Storage和 SQL Azure。

Service Bus 包含了针对这些问题的多项缓解措施。 以下各节介绍了每个问题及其相应的缓解措施。

限流

通过 Service Bus,节流机制可以实现协作消息速率管理。 每个单独的Service Bus节点都包含许多实体。 其中每个实体都在 CPU、内存、存储及其他方面对系统提出要求。 当其中任一方面检测到超出定义的阈值的使用情况时,Service Bus可以拒绝给定的请求。 调用方会接收到服务器繁忙异常,并在 10 秒后重试。

作为一种缓解措施,该代码必须读取错误信息并停止该消息的任何重试,持续至少 10 秒。 由于错误可能发生在多个客户应用程序之间,所以最好允许每个应用程序独立执行重试逻辑。 该代码可以通过对命名空间、队列或主题启用分区来减少被限流概率。

有关应用程序代码应如何处理限制问题的详细信息,请参阅有关限制模式的文档

Azure依赖项的问题

Azure中的其他组件偶尔会出现服务问题。 例如,当Service Bus使用的系统正在升级时,该系统可能会暂时体验到降低的功能。 若要解决此类问题,Service Bus定期调查和实施缓解措施。 这些缓解措施的副作用的确存在。 例如,若要处理存储的暂时性问题,Service Bus实现允许消息发送作一致工作的系统。 一般而言,大多数实体不会遇到此问题。 鉴于Azure Service Bus中的实体数量,有时需要此缓解措施,以应对一小部分Service Bus客户的需求。

单个子系统上的服务总线发生故障

使用任何应用程序时,情况可能会导致Service Bus的内部组件变得不一致。 当Service Bus检测到此情况时,它会从应用程序收集数据,以帮助诊断所发生的事情。 收集到数据后,会重新启动该应用程序以尝试使其返回一致状态。 此过程发生得相当迅速,导致实体看起来在长达数分钟内不可用,尽管通常的停机时间要短得多。

在这些情况下,客户端应用程序将生成超时异常或消息传送异常。 Service Bus以自动客户端重试逻辑的形式包含此问题的缓解措施。 重试期用完且未传递消息后,可以使用 异地灾难恢复或其他方法 切换到其他命名空间

后续步骤

在了解了 Service Bus 中异步消息传递的基础知识后,请阅读有关 Azure Service Bus 中可靠性的更多详细信息。