为什么需要客户端弹性模式

没有使用客户端弹性模式

下图展示了使用远程资源(如数据库和远程服务)的典型情境。在这个情境中不包含任何客户端弹性模式

在上图的情境中,三个应用以一种形式或另一种形式与三个不同的服务进行通信:

  • 应用程序A和B直接与 licensing 服务通信。

  • licensing 服务从数据库中检索数据并调用 organization 服务来执行一些工作。

  • organization 服务从一个完全不同的数据库平台检索数据,并调用另一个服务,即 inventory 服务,该服务来自第三方云服务提供商,其服务在很大程度上依赖于内部的网络附加存储(Network Attached Storage,NAS)设备将数据写入共享文件系统。

  • 应用程序C直接调用 inventory 服务。

在一个周末,网络管理员对 NAS 配置进行了一个小调整。这个更改似乎运行正常,但在星期一早上,对特定磁盘子系统的读取开始变得异常缓慢。

编写 organization 服务的开发人员从未预料到 inventory 服务会运行缓慢。因此,他们在编写代码时,将数据库的写入和从 inventory 服务的读取封装在了同一个事务内。当 inventory 服务开始运行缓慢时,不仅使得用于进行 inventory 服务请求的线程池开始产生任务积压,服务容器中的数据库连接池中的连接数量也被消耗殆尽。这些数据库连接会一直保持打开状态,因为对 inventory 服务的调用还未完成。

进一步的,licensing 服务开始耗尽资源,因为它正在调用 organization 服务,而 organization 服务正因 inventory 服务而运行缓慢。最终,三个应用程序都由于等待请求完成而耗尽资源,并停止响应。

使用了客户端弹性模式后

如果在调用分布式资源的每个点(无论是对数据库的调用还是对服务的调用)都实施了断路器模式,上述情景是可以避免的。

  • 如果 organization 服务在调用 inventory 服务时使用了断路器模式,那么当 inventory 服务开始表现不佳时,断路器就会跳闸,使得调用过程快速失败而不会占用线程资源。如果 organization 服务具有多个端点,只有调用 inventory 服务的特定端点会受到影响。organization 服务的其余功能仍然完好,可以满足用户请求。

  • licensing 服务从未直接调用 organization 服务。相反,当调用发生时,licensing 服务将调用委托给了断路器,断路器将接收到的调用封装在一个线程中(通常由线程池管理),该线程独立于调用者。通过将调用包装在线程中,客户端不再等待调用完成。相反,断路器监控线程,并在线程运行时间过长时终止调用。

图中展示了三种情景:

  1. 在第一种情景(Happy path)中,断路器维护一个计时器,如果对远程服务的调用在计时器超时之前完成,licensing 服务可以继续其工作。

  2. 在第二种情景中,即“部分降级”中,licensing 服务通过断路器调用 organization 服务。然而,这一次, organization 服务运行缓慢,因此在计时器超时之前未完成对远程服务的调用,断路器终止与远程服务的连接。然后,licensing 服务从调用中返回一个错误。

    如果对 organization 服务的调用超时,断路器会开始跟踪发生的故障次数。如果在特定时间段内发生了足够多次的服务错误,断路器便会“跳闸”,使得所有对 organization 服务的调用都会直接返回失败而不进行实际的调用。

  3. 在第三种情景中,licensing 服务知道 organization 服务存在问题,因此无需等待断路器超时。

    • 之后,它可以选择要么完全失败,要么执行备用代码。

    • 由于在断路器跳闸后,licensing 服务不再调用 organization 服务,因此 organization 服务得到了恢复的机会。

    • 断路器偶尔会允许调用处于降级状态的 organization 服务。如果这些调用连续成功足够多次,断路器会进行重置,恢复对 organization 服务的调用。

断路器模式提供的关键优势包括以下几点:

  1. 快速失败(Fail Fast): 当远程服务出现降级时,应用程序会迅速失败,防止资源枯竭问题(这个问题通常会导致整个应用程序宕机)。在大多数故障情况下,部分失效比完全失效更为可取。

  2. 优雅失败(Fail Gracefully): 通过设定超时并快速失败,断路器模式使我们能够以优雅的方式失败,或者寻找替代机制来满足用户的请求。

  3. 无缝恢复(Recover Seamlessly): 由于断路器模式充当了中间人的角色,因此断路器可以定期检查所请求的资源是否已重新上线,并在无需人工干预的情况下重新启用对该资源的访问。

    在一个拥有数百个服务的庞大云应用中,这种优雅的恢复至关重要,因为它能够显著缩短恢复服务所需的时间。

Last updated