高并发系统限流策略,线程隔离

在高并发系统里面有三把利器可以用来保护系统不被瞬时的高并发访问击溃:缓存,降级以及限流。这里在借鉴了张开涛大神的一些思路整理了下面三种方案:

缓存

在一个大型系统中,如果不存在缓存,系统可能分分钟因为数据库的瓶颈限制而导致服务崩溃瘫痪,使用缓存不仅仅可以带来系统访问速度的提升,并发量的增大以及保护数据库。一般大型湾站主要是以“读”为主,即便是以“写”为主的系统,缓存也扮演着非常重要的角色,例如累计数据批量写入,内存里面的缓存队列,HBase写数据的机制都是通过缓存来提升系统的吞吐量或者实现系统保护的措施。

降级

服务降级是当服务器压力剧增的时候,根据当前业务情况以及流量对一些服务页面有策略的降级,以便释放服务器资源以保证核心人物的正常运行降级往往会指定不同的级别,以面对不同的异常等级执行不同的处理,根据服务方式,可以拒绝服务,业务科延迟服务,有时候可以随机服务,根据服务范围,可以砍掉某个功能,也可以砍掉某些模块。粽子服务降级需要根据不同的业务需求采用不同的降级策略,主要核心理念:服务有损失,但总比没有的好。

限流

限流可以被认为是服务降级的一种,限流就是限制系统输入输出流量以达到保护系统的目的。一般来说为了系统的稳定运行,一旦达到系统需要限制的阈值,就需要限制流量并采用一些措施来完成限制流量的目的,比如延迟处理,拒绝处理,或者部分拒绝处理。

限流算法

常见的限流算法有:计数器,漏桶以及令牌桶算法

计数器算法

计数器是最为简单除暴的算法,如果某个服务最多每秒处理100个请求,我们可以设置一个1秒钟的滑动窗口,每100毫秒移动一次,每个移动都需要记录当前服务请求的次数,内存中需要保留10次请求次数,可以用LinkedList,格子每次移动的时候需要判断一次,当前访问次数和linkedList钟最后一个相差是否超过100,如果超过就需要限流了。

很明显,当滑动窗口的格子划分越多,那么滑动窗口的滚动九月平滑,限流的统计也就会越精准

漏桶算法

漏桶算法吉leaky bucket,他是一种非常常用的限流算法那,可以用来实现流量整形(traffic shaping)以及流量控制(traffic policing)

漏桶算法的主要概念如下:

一个固定的漏桶,按照常量固定速率流出水滴

如果桶是空的,则不需要流出水滴

可以以任意速率流入水滴到水桶

如果流入水滴超过了桶的流量,则流入的水滴溢出了(被丢弃),而桶的容量是不变的。

漏桶算法比较好实现,在单机系统中可以使用队列来实现,在分布式环境中消息中间件或者redis都是可选的方案

令牌桶算法

令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里面添加令牌,令牌桶算法基本上可以使用下面的几个概念来描述:

令牌按照固定的速率被放入到令牌桶中,比如每秒放入100个

同种最多存放b个令牌,当桶满时新添加的令牌被救起或者拒绝。

当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上。

如果同种的令牌不足n个,则不会删除令牌,切该数据包将被丢弃(要么丢弃要目在缓存区中等待) 

令牌算法是根据放入令牌的速率来控制输出的速率,我们可以理解为消息的处理程序,执行某段业务或者调用某个rpc

漏桶和令牌桶的比较

令牌桶可以在运行时控制和调整数据处理的速率,处理某时的突发流量,放令牌的频率增加可以提升整体数据的处理的速度。而通过每次获取令牌的个数增加或者放慢令牌的方法速度和降低整体数据处理速度,而漏桶不行,因为它的流出速率是固定的,程序处理速度也是固定的,整体而言,令牌桶算法更优,但实现更为复杂。

限流算法实现

guava

Guava是一个goole的开源项目,包含了若干个被goole的Java项目广泛依赖的核心库,其中的rateLimiter提供了令牌桶算法的实现:平滑突发限流(SmoothBursty)和平滑预热限流(SmoothWarmingUp)

发布了18 篇原创文章 · 获赞 0 · 访问量 455

猜你喜欢

转载自blog.csdn.net/qq_36236038/article/details/104484959