Java编程——服务器设计方案之应用限流

前言程序员

在一个高并发系统中对流量的把控是很是重要的,当巨大的流量直接请求到咱们的服务器上没多久就可能形成接口不可用,不处理的话甚至会形成整个应用不可用。web

好比最近就有个这样的需求,我做为客户端要向kafka生产数据,而kafka的消费者则再源源不断的消费数据,并将消费的数据所有请求到web服务器,虽然说作了负载(有4台web服务器)但业务数据的量也是巨大的,每秒钟可能有上万条数据产生。若是生产者直接生产数据的话极有可能把web服务器拖垮。算法

对此就必需要作限流处理,每秒钟生产必定限额的数据到kafka,这样就能极大程度的保证web的正常运转。服务器

其实无论处理何种场景,本质都是下降流量保证应用的高可用。并发

常见算法分布式

对于限流常见有两种算法:高并发

漏桶算法学习

令牌桶算法spa

漏桶算法比较简单,就是将流量放入桶中,漏桶同时也按照必定的速率流出,若是流量过快的话就会溢出(漏桶并不会提升流出速率)。溢出的流量则直接丢弃。code

以下图所示:

这种作法简单粗暴。

漏桶算法虽然说简单,但却不能应对实际场景,好比忽然暴增的流量。

这时就须要用到令牌桶算法:

令牌桶会以一个恒定的速率向固定容量大小桶中放入令牌,当有流量来时则取走一个或多个令牌。当桶中没有令牌则将当前请求丢弃或阻塞。

相比之下令牌桶能够应对必定的突发流量.

RateLimiter实现

对于令牌桶的代码实现,能够直接使用Guava包中的RateLimiter。

调用结果以下:

代码能够看出以每秒向桶中放入两个令牌,请求一次消耗一个令牌。因此每秒钟只能发送两个请求。按照图中的时间来看也确实如此(返回值是获取此令牌所消耗的时间,差很少也是每500ms一个)。

使用有几个值得注意的地方:

容许先消费,后付款,意思就是它能够来一个请求的时候一次性取走几个或者是剩下全部的令牌甚至多取,可是后面的请求就得为上一次请求买单,它须要等待桶中的令牌补齐以后才能继续获取令牌。

总结

针对于单个应用的限流够用了,若是是分布式环境能够借助Redis来完成。
    程序员学习交流群:878249276,欢迎一到五年的工程师加入,合理利用本身每一分每一秒的时间来学习提高本身,不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!复制代码
相关文章
相关标签/搜索