1.微服务限流随着微服务的流行,服务和服务之间的稳定性变得越来越重要 。缓存、降级和限流是保护微服务系统运行稳定性的三大利器 。
缓存的目的是提升系统访问速度和增大系统能处理的容量,而降级是当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉,待高峰或者问题解决后再打开,而有些场景并不能用缓存和降级来解决,比如稀缺资源、数据库的写操作、频繁的复杂查询,因此需有一种手段来限制这些场景的请求量,即限流 。
比如当我们设计了一个函数,准备上线,这时候这个函数会消耗一些资源,处理上限是1秒服务3000个QPS,但如果实际情况遇到高于3000的QPS该如何解决呢?
所以限流的目的应当是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率就可以拒绝服务、等待、降级 。
学习如何去实现一个分布式限流框架,首先,我们需要去了解最基本的两种限流算法 。
2.限流算法【微服务架构下的分布式限流方案思考】2.1漏桶算法
漏桶算法思路很简单,水(也就是请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率 。示意图(来源网络)如下:
文章插图
2.2令牌桶算法
令牌桶算法和漏桶算法效果一样但方向相反的算法,更加容易理解 。随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入令牌(想象和漏洞漏水相反,有个水龙头在不断的加水),如果桶已经满了就不再加了 。新请求来临时,会各自拿走一个令牌,如果没有令牌可拿了就阻塞或者拒绝服务 。示意图(来源网络)如下:
文章插图
2.3算法选择
漏桶算法与令牌桶算法的区别在于,漏桶算法能够强行限制数据的传输速率,令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发情况 。令牌桶还有一个好处是可以方便的改变速度 。一旦需要提高速率,则按需提高放入桶中的令牌的速率 。所以,限流框架的核心算法还是以令牌桶算法为主 。
3.本地限流已知上面讲述的令牌桶算法的原理,如何通过代码实现?
本地限流的实现可以用Long长整型作为令牌桶,为了达到无锁,建议使用Long的原子类型AtomicLong,使用AtomicLong的好处就是可以非常方便的对其进行CAS加操作与CAS减操作(也就是令牌桶令牌的放入与拿取),以避免线程的上下文切换的开销,核心CAS算法如下:
文章插图
根据上述了解的令牌桶算法可以得知,令牌桶需要一个ScheduledThread不断的放入令牌,这部分的代码如下:
文章插图
4.分布式限流概述分布式限流需要解决什么问题呢?我想至少有下面几个:
1.动态规则:比如限流的QPS我们希望可以动态修改,限流的功能可以随时开启、关闭,限流的规则可以跟随业务进行动态变更等 。
2.集群限流:比如对Spring%20Cloud微服务架构中的某服务下的所有实例进行统一限流,以控制后续访问数据库的流量 。
3.熔断降级:比如在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误 。
可选的其它几个功能,诸如实时监控数据、网关流控、热点参数限流、系统自适应限流、黑白名单控制、注解支持等,这些功能其实可以非常方便的进行扩展 。
5.分布式限流方案分布式限流的思想我列举下面三个方案:
1.redis令牌桶
这种方案是最简单的一种集群限流思想 。在本地限流中,我们使用Long的原子类作令牌桶,当实例数量超过1,我们就考虑将Redis用作公共内存区域,进行读写 。涉及到的并发控制,也可以使用Redis实现分布式锁 。
方案的缺点显而易见,每取一次令牌都会进行一次网络开销,而网络开销起码是毫秒级,所以这种方案支持的并发量是非常有限的 。
2.QPS统一分配
这种方案的思想是将集群限流最大程度的本地化 。
推荐阅读
- 浪潮TS850服务器,MegaRAID卡,如何做RAID?
- 微信最新封杀违规外链的几点看法
- “秋老虎”虽热,实已入秋,秋季养生,宜收敛养性,饮食微酸
- 微软|一键为Win11还原经典任务栏+开始菜单的工具发新版:更好用了
- 沂源翠微高山茶香起来
- 名茶小镇全情服务亚洲空手道赛前训练
- 山东,沂源翠微高山茶香起来
- 茶香四溢 临安电力服务暖人心
- 如何使用pssh自动化工具批量管理linux服务器
- 步步深入MySQL:架构<查询执行流程>SQL解析顺序