
| 问题和背景说明

首先我们来看下限流熔断的出现背景。比如上图的一个微服务间调用关系,我们用这个图作为参考来进行一些常见的场景和问题。
某一个API接口服务调用导致整体资源被耗尽
这是一个比较典型的场景,即某一个API接口服务的大并发,大数据量调用导致服务器线程和内存资源的全部耗尽。
对于API接口服务调用,往往并不怕大并发调用,而是怕长耗时和大数据量的调用,这种接口调用导致连接一直被占用,而是大数据量情况下内存资源也一直被占用而服务是否。在这种场景下往往导致线程池满,或者场景的JVM内存溢出问题,将直接导致整个JVM内存溢出宕机。
即我们常说的单个API服务问题导致所有资源被抢占,而影响到所有API接口调用。
常说的服务调用引发雪崩
在微服务架构下,微服务API接口间相互依赖,形成服务链调用关系,如上图。在这种情况下依赖的API接口服务如果出现问题,那么就会导致上层的各个消费方都出现调用异常,而导致整体服务链调用雪崩。
比如上图里面如果C1出现性能问题,那么将直接导致B1和B2都出现性能问题,而由于B层出现的性能问题又会快速的传递到A层,导致A层相关的API接口服务全部出现问题。
通过上面初步分析也可以看到,服务限流熔断简单来说就是不要因为单个API接口服务出现的异常或性能问题而影响都整体API网关或微服务架构的运行,牺牲或拒绝一个服务的访问往往是确保了更多的服务能够正常被消费和调用。
在梳理清楚以上概念后,我们再回来看下服务限流熔断本身的概念。
限流熔断的基本概念
对于限流熔断,我原来给过一个概念,简单来说限流就是服务请求调用要排队,只给你一个线程池总数,超过就等待,即使你瞬间的请求并发再大也需要慢慢进入。而对于熔断则我们常说的整个服务都处于不可用状态。
今天我们对这个概念重新进行下说明。如下图:

一个限流策略既可以是让消费方的服务请求进行排队,也可以是对触发某个规则后直接对某个特定的消费方调用进行拒绝,比如上图仅拒绝Consumer2的调用,而对于其它消费方调用仍然放行。而对于熔断策略则一定是整个服务全部进行拒绝访问,注意这种熔断不一定必须是服务下线或状态变更,也可以是直接在限流熔断拦截器上对所有入口请求进行拒绝。
| 整体实现思路说明
在讲具体的实现方案的时候先讲下整体的实现思路。
从前面的分析我们也看到,实际上对于限流和熔断更多的是控制的资源单位和粒度不一样,因为我们希望的是构建一套算法来满足对所有的问题场景下的需求。由于服务限流熔断更多的是需要对服务进行拦截处理,我们也看到限流熔断器一般都会配合API网关,微服务网关等使用,而不是独立的存在。
01-对于资源粒度的考虑
在阿里的Sentinel的实现里面有几个重要的概念,一个是资源,一个是Slot,一个是实现机制中的滑动时间窗口,但是初步看好像无法配置到单个消费方+服务这个层面。
对资源粒度,初步分析应该包括了多个层次,从最粗的资源到最细化的资源,在传统的资源粒度考虑里面我们往往并不会考虑到某个微服务或业务系统这个粒度,但是如果从API网关的限流熔断,对API网关本身的性能保护来说,这个还是有必要。
比如用户中心这个微服务,实际上提供29个API服务接口。
当用户中心微服务模块本身出现问题的时候,这29个微服务可能都会出现性能访问缓慢,那么需要的是对整个用户中心接入的API服务全部限流和熔断。

即我们对资源本身的颗粒度进一步细化,从最细粒度到最粗粒度可以分为:
最细粒度:API消费方+API服务+API提供方
熔断层:API服务+API提供方
熔断范围:API提供方(对API服务提供方所有服务进行熔断)
为啥考虑这个问题,搞清楚了资源管控的颗粒度,我们一个方面是要在规则配置的时候支持多种层次的配置,一个方面就是我们实际实时数据计算的时候需要进行颗粒度的考虑。
02-对规则的关键说明
要实现限流熔断,简单来就是三个方面的内容,一个就是资源,一个是就是规则,一个就是通过计算汇总处理过程。计算过程最终就是来判断在某一个时间点当前的实际数据是否已经满足了规则触发的要求,如果满足要求就触发规则进行限流熔断。
对于规则,首先要考虑维度定义,而维度本身就是API接口服务运行实例的汇总统计数据,那么这些场景的维度包括了:
API服务运行时长
API服务单位时间的运行次数
API服务运行数据量
而这三个基础维度本身又会进一步产生其它扩展维度,比如我们常说的最大数据量,评价数据量,运行失败次数,运行成功率,运行最大耗时等。
而对于具体的规则,我们希望最简单处理,即:
某一个指标 大于 或小于 我们预定的某一个阈值,就算规则满足。
其次就是可以定义复合规则。复合规则也简单处理为规则的与或处理,即:
规则1和规则2同时满足,就算整体规则满足
而对于规则本身的作用范围,我在前面已经讲到,即资源本身的不同粒度。规则可以最细化的作用到某一个特定的消费方调用的某一个特定服务,也可以是作用到某个服务所有消费方。

03-对计算逻辑的关键说明
对于用户查询API接口,在5分钟内调用次数大于1万次即整体熔断 对于CRM系统消费产品查询接口,在10分钟内如果平均时长大于30秒则拒绝CRM访问 对于订单更新API接口,如果失败率超过1%则全部熔断

Hystrix滑动窗口计算逻辑
| 限流熔断整体实现逻辑

对于该图,实际可以看到,如果按 Slot计算逻辑单元划分的思路可以分为:
基于配置的规则将服务运行实例按资源颗粒度匹配要求存到实例数据暂存区
进行第一次汇总计算
将汇总数据推入到滑动时间窗口数组
基于规则配置进行二次汇总计算
对限流熔断是否触发进行判断和处理
规则1:对于CRM消费getCustomer接口进行限流,10分钟调用>1万即拒绝
规则2:对于getProductinfo接口流控,5分钟错误>1%则整体熔断
规则3:对于ERP系统提供所有服务,1分钟平均时长>30秒则整体熔断
| 限流熔断实现逻辑和API网关能力的解耦
