应用程序和基础结构复原能力
复原能力是能够从暂时性故障中恢复。 应用的恢复策略可还原正常功能,对用户的影响最小。 云环境中可能会发生故障,应用应以最大程度减少停机时间和数据丢失的方式做出响应。 在理想情况下,你的应用可以正常处理故障,而用户不知道有问题。
由于微服务环境可能不稳定,因此设计应用预期并处理部分故障。 例如,部分故障可能包括代码异常、网络中断、无响应的服务器进程或硬件故障。 即使是计划内的活动(例如将容器移到 Kubernetes 群集中的其他节点)也可能会导致暂时性故障。
复原方法
在设计可复原的应用程序时,通常需要在故障快速和正常降级之间进行选择。 快速失败意味着应用程序会在出现问题时立即引发错误或异常,而不是尝试恢复或解决问题。 这样就可以快速识别和修复问题。 正常降级意味着即使某些组件发生故障,应用程序也会尝试保持有限的容量运行。
在云原生应用程序中,服务必须正常处理故障,而不是快速故障。 由于微服务是分散的且可独立部署,预计部分失败。 快速故障将使一个服务中的故障能够快速关闭依赖服务,从而降低整体系统复原能力。 相反,应对微服务进行编码,以预测和容忍内部和外部服务故障。 这种正常降级允许整个系统继续运行,即使某些服务中断。 可以持续关键的面向用户的函数,避免完全中断。 正常故障还允许干扰的服务时间恢复或自我修复,然后再影响系统的其余部分。 因此,对于基于微服务的应用程序,正常降级更符合故障隔离和快速恢复等复原最佳做法。 它防止本地事件跨系统级联。
有两种基本方法支持正常降级,具有复原能力:应用程序和基础结构。 每个方法都有优点和缺点。 根据情况,这两种方法都适用。 本模块介绍如何实现 基于代码 的复原和 基于基础结构 的复原能力。
基于代码的复原能力
为了实现基于代码的复原能力,.NET 具有一个扩展库,用于复原和暂时性故障处理 Microsoft.Extensions.Http.Resilience
。
它使用流畅、易于理解的语法以线程安全的方式生成故障处理代码。 有几个复原策略定义故障处理行为。 在本模块中,你将重试和断路器策略应用到 HTTP 客户端作。
重试策略
重试策略正是名称的含义。 如果收到错误响应,则会在短暂等待后重试请求。 每次重试时,等待时间都会增加。 增加可以是线性的或指数的。
达到最大重试次数后,策略会放弃并引发异常。 从用户的角度来看,应用通常需要更长的时间才能完成某些作。 应用可能需要一些时间才能通知用户无法完成该作。
断路器策略
断路器策略通过暂停尝试与其通信,使目标服务在多次失败后中断。 该服务可能遇到严重问题,暂时无法响应。 在定义的连续失败次数后,连接尝试将暂停, 并打开 线路。 在此等待期间,目标服务上的其他作会立即失败,甚至无需尝试连接服务。 等待时间过后,将再次尝试该作。 如果服务成功响应,则线路 关闭 ,系统恢复正常。
基于基础结构的复原能力
若要实现基于基础结构的复原能力,可以使用 服务网格。 除了不更改代码的复原能力外,服务网格还提供流量管理、策略、安全性、强标识和可观测性。 你的应用程序与这些被迁移到基础设施层的操作功能实现了分离。
与基于代码的方法的比较
基于基础结构的复原方法可以使用基于指标的视图,以便实时适应群集条件。 此方法添加另一个维度来管理群集,但不添加任何代码。
使用基于代码的方法,可以:
- 需要猜测适合采用哪些重试和超时参数。
- 专注于特定的 HTTP 请求。
无法合理响应应用代码中的基础结构故障。 请考虑同时处理的数百个或数千个请求。 即使是指数回退(时间请求计数)的重试也可能会使服务不堪负重。
相比之下,基于基础结构的方法不知道应用内部。 例如,复杂的数据库事务对服务网格不可见。 此类事务只能受到基于代码的方法的故障保护。
在即将到来的单元中,你将在代码和 Linkerd 服务网格中使用 .NET HTTP 复原为基于微服务的应用实现复原能力。