熔断、降级和限流之间的区别
当我们的系统整体访问量突然剧增,大量的请求在瞬间涌入,或者某个下游服务突然异常,大量请求调用阻塞又或者在可预见的将来,几天内比如,会有一波流量的高峰(比如双十一)。这个时候,我们要怎么做才能保证系统正常提供功能,或者说,最低要求,如何保证系统核心业务能正常提供功能?
这种情况下,在无法提升服务的负载能力的时候,我们可以采取三种措施:熔断、降级或限流。
熔断
当我们的下游服务因为某些原因出现故障,导致调用超时或者失败时,我们这时候就不应该继续不断重试加重下游服务的问题,而是应该及时失败。
熔断模式可以防止应用程序不断地尝试可能超时和失败的服务,能达到应用程序执行而不必等待下游服务修正错误服务。
并且熔断器模式还能让应用程序自我诊断下游系统的错误是否已经修正,如果没有,不放量去请求,如果请求成功了,慢慢的增加请求,再次尝试调用。
熔断怎么做
首先,需秉持的一个中心思想是:量力而行。因为软件和人不同,没有奇迹会发生,什么样的性能撑多少流量是固定的。这是根本。
然后,这四步走分别是:
- 定义一个识别是否处于“不可用”状态的策略
- 切断联系
- 定义一个识别是否处于“可用”状态的策略,并尝试探测
- 重新恢复正常
降级
降级的目的用一句话概括就是:将有限的资源效益最大化。当我们的服务器压力剧增为了保证核心功能的可用性 ,而选择性的降低一些功能的可用性,或者直接关闭该功能。这就是典型的丢车保帅了。
牺牲用户体验
- 为了减少对「冷数据」的获取,禁用列表的翻页功能。
- 为了放缓流量进入的速率,增加验证码机制。
- 为了减少“大查询”浪费过多的资源,提高筛选条件要求(禁用模糊查询、部分条件必选等)。
- 用通用的静态化数据代替「千人千面」的动态数据。
- 甚至更简单粗暴的,直接挂一个页面显示「XX功能在XX时间内暂时关闭」。
此类方案虽然或多或少降低了用户的体验,但是在某些时期,有些功能并不是「刚需」。以此换取对系统的保护是笔划算的买卖。
牺牲功能完整性
比如通过临时关闭「风控」、取消部分「条件是否满足」的判断(如,将积分商品添加到购物车时判断积分够不够)等操作,减少这类「验证」动作以释放更多的资源。
又或者将原本info、warning级别的日志采集关闭或者直接不采集,仅采集error以及fault级别的日志。
牺牲时效性
比如原先在商品页会显示当前还剩多少个库存,现在可以调整成固定显示「有货」。
以及将一些原本就是异步进行的操作,处理效率放缓,甚至暂缓一段时间。如,送积分、送券等等。
降级怎么做
定级定序
把不同的服务按照功能是否核心,定义不同的级别,相同级别的服务,再定义它们的顺序。总之,越重要的服务越后面降级。
有一点是需要格外注意的:某个程序所依赖的下游程序的级别不能低于该程序的级别。
限流
限流的作用就是提供完成的系统功能,但是会限制进出系统的流量。
限流一般分三步:获取系统的能力上限、指定限流的策略;处理被限制的流量
获取系统的能力上限
压测
指定限流的策略
计算某段时间内的总请求量或者总请求量。