你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
分布式系统中不可避免的故障。 硬件可能发生故障。 网络也有可能发生暂时性故障。 整个服务、数据中心甚至 Azure 区域很少遇到中断,但工作负荷体系结构必须考虑到这些中断。 在工作负荷设计早期解决复原和恢复问题。
设计在发生故障时自我修复的应用程序。 使用以下方法:
- 检测故障。
- 从容应对故障。
- 记录和监视失败以提供作见解。
将应用程序设计为在发生故障时自我愈合
将响应与工作负荷的可用性要求保持一致。 例如,如果需要高可用性,则可以部署到一个区域中的多个可用性区域。 为了避免 Azure 区域遇到中断时出现中断,可以自动故障转移到次要区域。 与单区域部署相比,此方法会增加成本和降低性能。
不要只关注罕见的大型事件,例如区域性中断。 同样或更多地关注本地生存期故障,例如网络连接丢失或数据库连接失败。
自我修复工作负荷设计是 Azure Well-Architected 框架可靠性支柱的基础,它强调构建可承受故障并恢复到正常运行状态的复原系统。 构建自我修复策略以支持工作负荷的可用性目标,包括服务级别目标(SLO)。
Recommendations
使用异步通信的分离组件。 在时间和空间方面设计解耦的组件。 及时分离意味着组件不需要同时存在用于通信。 在空间中分离意味着发送方和接收方不必在同一进程中运行。 分离的组件应使用事件相互通信,这有助于最大程度地减少级联故障的可能性。
重试失败的作。 暂时性故障可能发生,因为网络连接暂时丢失、数据库连接断开或服务繁忙时超时。 在应用程序中构建重试逻辑来处理暂时性故障。 对于许多 Azure 服务,客户端 SDK 可实施自动重试。 有关详细信息,请参阅暂时性故障处理和重试模式。
实现运行状况终结点监视。 每个服务都应公开一个运行状况终结点,该终结点指示其当前状态及其依赖项的状态。 外部监视系统、负载均衡器和业务流程协调程序使用这些运行状况终结点来确定服务是否正常运行并相应地路由流量。 有关详细信息,请参阅运行状况终结点监视模式。
保护失败的远程服务。 最好在暂时性故障后重试,但永久性故障可能会重载失败服务并导致级联故障。 当作可能失败时,使用 断路器模式 快速失败,而无需进行远程调用。
隔离关键资源。 如果资源(如线程或套接字)不会及时释放,则一个子系统中的故障可能会级联,这可能会导致资源耗尽。 使用 Bulkhead 模式 将系统分区为独立组,以便一个分区中的故障不会影响整个系统。
执行负载调配。 应用程序可能会遇到流量突然激增,导致后端服务不堪重负。 使用 Queue-Based 负载调配模式 将工作项排队以异步运行。 队列充当缓冲负载峰值的缓冲区。
故障转移。 如果无法连接某个实例,请切换到另一个实例。 对于无状态组件(如 Web 服务器),请将多个实例放置在负载均衡器或流量管理器后面。 对于有状态组件(如数据库),请使用副本并实现故障转移机制。 根据数据存储及其复制方式,应用程序可能需要处理最终一致性。
补偿失败的事务。 一般情况下,请避免分布式事务,因为它们需要跨服务和资源进行协调。 相反,应该用较小的单个事务组成操作。 如果作在中途失败,请使用 补偿事务模式 撤消已完成的步骤。
向长时间运行的事务添加检查点。 如果长时间运行的作失败,检查点可提供复原能力。 当作重新启动时,例如,如果另一个虚拟机拾取它,它可以从最后一个检查点恢复。 请考虑实现一种机制,以定期记录有关任务的状态信息。 将此状态保存在持久存储中,运行任务的进程的任何实例都可以访问。 如果进程关闭,则另一个实例可以从最后一个检查点恢复工作。 NServiceBus 和 MassTransit 等库提供此功能。 它们以透明方式保留状态,间隔与 Azure 服务总线中队列的消息处理保持一致。
正常降级,并在故障期间保持响应。 有时无法解决问题,但可以提供有用的缩减功能。 例如,如果应用程序无法检索书籍封面缩略图图像,则可能显示占位符图像。 与订单处理相比,整个子系统可能是非关键子系统,例如电子商务网站上的产品建议。
限制客户端。 有时,少数用户会创建过多的负载,这可以减少应用程序对其他用户的可用性。 在这种情况下,将客户端限制一段时间。 有关详细信息,请参阅 限制模式。
阻止坏演员。 限制并不意味着恶意意图。 这意味着客户端超出了其服务配额。 但如果客户端持续超出其配额或在其他方面具有不良行为,则可能需要进行阻止。 定义一个带外进程,供用户请求取消阻止。
使用领导人选举。 需要协调任务时,请使用 领导选举模式 选择协调器。 此方法可确保协调器不是单一故障点。 如果协调器失败,系统将选择一个新协调器。 考虑使用 Apache ZooKeeper 等预生成解决方案,而不是实现自定义领导者选举算法。
使用故障注入进行测试。 成功路径通常会收到彻底的测试,但失败路径不会。 在触发故障路径之前,系统可以在生产环境中运行很长时间。 使用故障注入通过触发或模拟故障来测试系统的复原能力。
实现混乱工程。 混沌工程通过将故障或异常情况随机引入生产实例来扩展故障注入的概念。 Azure Chaos Studio 等工具可帮助你运行受控的混沌试验,以识别自我修复策略中的弱点。
使用可用区域 许多 Azure 区域提供 可用性区域,这些区域是区域内独立的数据中心集。 可以 按区域部署一些 Azure 服务,这可以确保它们驻留在特定区域中,并有助于降低同一工作负荷中组件之间的通信延迟。 或者,可以使用 区域冗余部署某些服务,这意味着 Azure 会自动跨区域复制资源以实现高可用性。 请考虑哪种方法为解决方案提供最佳权衡。 有关详细信息,请参阅 可用性区域和区域的建议。 某些支持可用性区域的服务要求将服务配置为在这些区域中专门横向扩展,例如将最小实例计数设置为 3。
不要添加超出需要的内容。 自我修复策略必须与成本约束、性能目标和可接受的停机时间级别保持一致。 避免在不需要这种自动恢复级别的工作负载中实现自我修复功能。