人的知识就好比一个圆圈,圆圈里面是已知的,圆圈外面是未知的。你知道得越多,圆圈也就越大,你不知道的也就越多。

0%

微服务-断路器(熔断、降级、限流、超时监控)

概述

众所周知,微服务架构具有许多优点。包含松散耦合,自治服务,分散治理,更容易连续交付等。但与此同时,它使架构变得脆弱,因为每个用户的操作结果都会调用多个服务。它通过网络上的远程调用替换了单体系结构中的内存调用。但是当一个或多个服务不可用或表现出高延迟时,会导致整个系统出现级联故障。服务客户端的重试逻辑只会使情况更糟糕,并且可能导致系统彻底的崩溃。

断路器模式有助于防止跨多个系统的这种灾难性级联故障。断路器模式允许我们构建容错和弹性的系统,当关键服务不可用或具有高延迟时,系统仍然可以正常运行。

容错模式

容错模式

服务熔断

当调用目标服务的请求和调用大量超时或失败,服务调用方为避免造成长时间的阻塞造成影响其他服务,后续对该服务接口的调用不再经过进行请求,直接执行本地的默认方法。

服务降级

为了保证核心业务在大量请求下能正常运行,根据实际业务情况及流量,对部分服务降低优先级,有策略的不处理或用简单的方式处理。

服务限流

当系统资源不够,不足以应对大量请求,对系统按照预设的规则进行流量限制或功能限制。

回退

在熔断或者限流发生的时候,应用程序的后续处理逻辑是什么?回退是系统的弹性恢复能力,常见的处理策略有,直接抛出异常,也称快速失败(Fail Fast),也可以返回空值或缺省值,还可以返回备份数据,如果主服务熔断了,可以从备份服务获取数据。

容错理念

  • 凡是依赖都可能会失败
  • 凡是资源(CPU/Memory/Threads/Queue)都有限制
  • 网络并不可靠
  • 延迟是应用稳定性杀手

断路器模式

断路器模式源于 Martin Fowler 的 Circuit Breaker 一文。“断路器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

状态机模式

断路器的实现采用状态机模式,它有 3 种不同的状态:关闭、打开和半打开。

  • 关闭:当一切正常时,断路器保持闭合状态,所有调用都能访问到服务。当故障数超过预定阈值时,断路器跳闸,并进入打开状态。
  • 打开:断路器在不执行该服务的情况下为调用返回错误。
  • 半开:超时后,断路器切换到半开状态,以测试问题是否仍然存在。如果在这种半开状态下单个调用失败,则断路器再次打开。如果成功,则断路器重置回正常关闭状态。

状态机模式

断路器模式

舱壁隔离模式

舱壁隔离模式,顾名思义,该模式像舱壁一样对资源或失败单元进行隔离,如果一个船舱破了进水,只损失一个船舱,其它船舱可以不受影响 。线程隔离就是舱壁隔离模式的一个例子,假定一个应用程序 A 调用了 Svc1/Svc2/Svc3 三个服务,且部署 A 的容器一共有 120 个工作线程,采用线程隔离机制,可以给对 Svc1/Svc2/Svc3 的调用各分配 40 个线程,当 Svc2 慢了,给 Svc2 分配的 40 个线程因慢而阻塞并最终耗尽,线程隔离可以保证给 Svc1/Svc3 分配的 80 个线程可以不受影响,如果没有这种隔离机制,当 Svc2 慢的时候,120 个工作线程会很快全部被对 Svc2 的调用吃光,整个应用程序会全部慢下来。

线程池隔离与信号量隔离

概念

线程池与信号量隔离

  • 线程池隔离:每次都开启一个单独线程运行。它的隔离是通过线程池,即每个隔离粒度都是个线程池,互相不干扰。
  • 信号量隔离:每次调用线程,当前请求通过计数信号量进行限制,当信号大于了最大请求数(maxConcurrentRequests)时,进行限制。

对比

特性对比:

线程池隔离 信号量隔离
隔离原理 每个服务单独用线程池 通过信号量的计数器
是否支持熔断 支持,当线程池到达MaxSize后,再请求会触发fallback接口进行熔断 支持,当信号量达到maxConcurrentRequest后,再请求会触发fallback
是否支持超时 支持,可直接返回 不支持,如果阻塞,只能通过调用协议
是否支持异步调用 可以是异步,也可以是同步。看调用的方法 同步调用,不支持异步
资源消耗 大,大量线程的上下文切换,容易造成机器负载高 小,只是个计数器

优缺点对比:

优点 不足 适用
线程池隔离 支持任务排队和超时
支持异步调用
线程调用会产生额外的开销 不受信客户
有限扇出
信号量隔离 轻量,无额外开销 不支持任务排队和主动超时
不支持异步调用
受信客户
高扇出(网关)
高频高速调用(cache)

案例

线程池隔离案例:
线程池隔离案例

主流开源断路器概览

Sentinel Hystrix resilience4j
隔离策略 信号量隔离(并发线程数限流) 线程池隔离/信号量隔离 信号量隔离
熔断降级策略 基于响应时间、异常比率、异常数 基于异常比率 基于异常比率、响应时间
实时统计实现 滑动窗口(LeapArray) 滑动窗口(基于 RxJava) Ring Bit Buffer
动态规则配置 支持多种数据源 支持多种数据源 有限支持
扩展性 多个扩展点 插件的形式 接口的形式
基于注解的支持 支持 支持 支持
限流 基于 QPS,支持基于调用关系的限流 有限的支持 Rate Limiter
流量整形 支持预热模式、匀速器模式、预热排队模式 不支持 简单的 Rate Limiter 模式
系统自适应保护 支持 不支持 不支持
控制台 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等 简单的监控查看 不提供控制台,可对接其它监控系统

参考资料

  1. 微服务与断路器
  2. Guideline: 从 Hystrix 迁移到 Sentinel
小礼物走一走,来 Github 关注我