使应用程序免受服务总线中断和灾难影响的最佳实践

任务关键型应用程序必须连续运行,即使是在计划外中断或灾难发生时。 针对数据处理资源灾难性中断的复原能力是许多企业的一项要求,某些情况下甚至是行业法规要求。 本文介绍可用于保护服务总线应用程序免受潜在的服务中断和灾难影响的技术。

Azure 服务总线已将各计算机甚至整个机架的灾难性故障风险分散到数据中心内跨多个故障域的群集中,并且实现了透明的故障检测和故障转移机制,使服务继续在有保证的服务级别内运行,而通常不会在此类故障发生时出现明显中断。

另外,中断风险会进一步分散到三个物理上分离的设备(可用性区域),并且该服务有足够的容量预留,可立即应对数据中心的全部灾难性损失。 在针对严重硬件故障甚至整个数据中心设施灾难性损失的恢复能力方面,容错域内支持可用性区域的全活动 Azure 服务总线群集模型优于任何本地消息中转站产品。 然而,仍有可能出现严重的情况,造成广泛的物理破坏,即使采取这些措施也无法充分防范。

服务总线异地灾难恢复和异地复制功能旨在使你更轻松地从如此大规模的灾难中恢复,并永久放弃发生故障的 Azure 区域,且无需更改应用程序配置。

中断和灾难

请务必注意“中断”和“灾难”的区别。

中断是指 Azure 服务总线暂时不可用,可能会影响服务的某些组件,如消息存储,甚至是整个数据中心。 但在问题解决后,服务总线将恢复可用。 通常情况下,中断不会导致消息或其他数据丢失。 组件故障的一个示例是特定的消息存储空间不可用。 数据中心范围中断的示例有数据中心电源故障或数据中心网络交换机故障。 中断可能会持续几分钟到几天的时间。 某些中断由于暂时性故障或网络问题只是短时间丢失连接。

根据定义,灾难是指永久或长期丢失服务总线群集、Azure 区域或数据中心。 该区域或数据中心不一定会恢复可用,或可能停用数小时或数天。 例如,火灾、洪灾或地震等可能导致此类灾难。 永久性灾难可能会导致一些消息、事件或其他数据丢失。 不过,在大多数情况下,都不应该会有数据丢失,并且在数据中心备份后,便可以恢复消息。

针对中断和灾难的防护

适用于“高级”层的 Azure 服务总线中有两项功能可提供异地灾难恢复。 首先,可以通过异地灾难恢复(元数据 DR)进行元数据(实体、配置、属性)的复制。 其次,可以通过目前为公共预览版的异地复制进行元数据和数据(消息数据和消息属性/状态更改)本身的复制。 不应将这两种异地灾难恢复功能与可用性区域相混淆。 无论是元数据 DR 还是异地复制,这两种异地恢复功能都可提供 Azure 区域(如中国东部和中国北部)之间的复原能力。

可用性区域在所有服务总线层上都可用,并支持在特定的地理区域(如中国东部)提供复原能力。 有关 Azure 中的灾难恢复的详细讨论,请参阅此文

高可用性和灾难恢复概念直接内置到 Azure 服务总线高级层中,无论是在同一区域中(通过可用性区域)还是跨不同的区域(通过异地灾难恢复和异地复制),都可以实现。

异地灾难恢复选项

异地灾难恢复

服务总线高级层支持命名空间级别的异地灾难恢复。 有关详细信息,请参阅 Azure 服务总线异地灾难恢复。 异地灾难恢复功能仅适用于高级层,可实现元数据灾难恢复,依赖于主要和辅助命名空间。 在进行异地灾难恢复的情况下,仅在主命名空间和辅助命名空间之间复制实体的元数据。

高级功能差异

异地灾难恢复(元数据 DR)功能将命名空间的元数据从主命名空间复制到次要命名空间。 它支持一次性故障转移到次要区域。 在客户启动的故障转移期间,命名空间的别名将重新指向次要命名空间,然后配对将会断开。 除元数据之外,没有复制任何数据,也没有复制 RBAC 分配。

可用性区域

所有服务总线层均支持可用性区域,可在同一 Azure 区域内提供故障隔离位置。 服务总线管理消息存储的三个副本(1 个主副本和 2 个辅助副本)。 服务总线使所有这三个副本保持同步,以用于数据和管理操作。 如果主副本发生故障,则可将其中一个辅助副本提升为主副本,而不会产生故障时间。 如果应用程序发现服务总线有暂时性中断,则 SDK 中的重试逻辑将自动重新连接到服务总线。

使用可用性区域时,将在该可用性区域中的数据中心之间复制元数据和数据(消息)。

注意

可用性区域支持仅适用于存在可用性区域的 Azure 区域

创建命名空间时,将自动为命名空间启用对可用性区域(如果在所选区域中可用)的支持。 使用此功能不会产生其他费用,在创建命名空间后,你无法禁用或启用此功能。

注意

以前需要将属性 zoneRedundant 设置为 true 才能启用可用性区域,但此行为已更改为默认启用可用性区域。 现有的命名空间也正在迁移到可用性区域,而属性 zoneRedundant 正在被弃用。 即使已启用可用性区域,属性 zoneRedundant 可能仍显示为 false

针对灾难的保护 - 标准层

若要使用服务总线标准层实现灾难复原能力,可以使用主动或被动复制。 对于每一种方法,如果必须在数据中心中断的情况下仍可访问给定的队列或主题,可以在两个命名空间中创建。 两个实体可以具有相同的名称。 例如,可在 contosoPrimary.servicebus.chinacloudapi.cn/myQueue 下访问主要队列,而在 contosoSecondary.servicebus.chinacloudapi.cn/myQueue 下访问其辅助队列。

注意

“主动复制”和“被动复制”设置是常规用途解决方案,不是服务总线的特定功能。 复制逻辑(发送到 2 个不同的命名空间)存在于发送方应用程序中,而接收方必须具有用于检测重复项的自定义逻辑。

如果应用程序不需要发送方到接收方的持续通信,则该应用程序可实施一个用于防止消息丢失的持久客户端队列,从而保护发送方免受任何暂时性服务总线错误的影响。

主动复制

主动复制对于每个操作都使用这两个命名空间中的实体。 任何发送消息的客户端都会发送同一条消息的两个副本。 第一个副本发送到主要实体(例如 contosoPrimary.servicebus.chinacloudapi.cn/sales),该消息的第二个副本发送到辅助实体(例如 contosoSecondary.servicebus.chinacloudapi.cn/sales)。

客户端从两个队列接收消息。 如果接收方处理了消息的第一个副本,则第二个副本会被取消。 要取消重复的消息,发送方必须用唯一标识符标记每一条消息。 必须用同一标识符标记消息的两个副本。 可使用 ServiceBusMessage.MessageIdServiceBusMessage.Subject 属性或自定义属性对消息进行标记。 接收方必须保留已接收消息的列表。

注意

主动复制方法会使操作数加倍,因此这种方法可能导致成本上升。

被动复制

在无故障的情况下,被动复制仅使用两个消息传送实体之一。 客户端将消息发送给活动实体。 如果针对活动实体的操作失败并返回错误代码,表明承载活动实体的数据中心可能不可用,则客户端将该消息的副本发送到备份实体。 此时活动实体和备份实体将互换角色。 发送方客户端会将旧的活动实体视为新的备份实体,并将旧的备份实体视为新的活动实体。 如果两次发送操作都失败,则两个实体的角色将保持不变并返回错误。

客户端从两个队列接收消息。 因为接收方可能接收同一条消息的两个副本,所以接收方必须取消重复消息。 可通过与主动复制中所述的相同方式取消重复消息。

一般来说,被动复制比主动重复更经济,因为在大多数情况下仅执行一个操作。 延迟、吞吐量和货币成本均与非复制场景相同。

使用被动复制时,在以下情况下可能丢失消息或接收两次消息:

  • 消息延迟或丢失:假定发送方将消息 m1 成功发送到主要队列,而该队列在接收方接收 m1 之前变为不可用。 发送方将后续消息 m2 发送给辅助队列。 如果主要队列是暂时不可用,则接收方会在该队列恢复可用后接收 m1。 发生灾难时,接收方可能永远不会收到 m1。
  • 重复接收:假定发送方将消息 m 发送到主要队列。 服务总线成功处理了 m 但无法发送响应。 发送操作超时后,发送方将向辅助队列发送 m 的一份相同副本。 如果接收方能够在主要队列变为不可用之前接收 m 的第一个副本,则接收方会在几乎同一时间接收 m 的两个副本。 如果接收方不能在主要队列变为不可用之前接收 m 的第一个副本,则接收方首先仅接收 m 的第二个副本,但会在主要队列变得可用后接收 m 的另一个副本。

使用 .NET Core 的 Azure 消息传送复制任务示例演示了命名空间之间的消息复制。

后续步骤

若要了解有关灾难恢复的详细信息,请参阅这些文章: