高并发之限流算法及实现

本文参考资料

高并发系统之限流特技:http://blog.csdn.net/g_hongjin/article/details/51649246

RateLimit--使用guava来做接口限流:http://blog.csdn.net/jiesa/article/details/50412027

秒杀:http://www.infoq.com/cn/articles/solution-to-the-architecture-of-spike-system

背景

2月22日10点负责的一个项目异常增多,服务几近不可用,并引发雪崩,造成其他项目也不可用。对日志进行分析后发现,服务调用量激增了10倍,最后经过扩容解决了问题,影响时间将近20分钟。事故原因:上游系统一个服务站点出现故障,导致大量请求过来,随后出现线程连接数爆满且出现很多请求超时,当调用方发现超时会不停的重试3次,这时候请求数瞬时成倍增长。

求索

流量激增,犹如暴雨导致河流流量增多,可能会超过大坝的防洪库容,需要泄洪保护大坝不被冲毁;也犹如家里的保险控制,一旦使用大功率的电器,保险有可能跳闸,保护电路不被烧毁。我们系统中如果有保险控制或防洪大坝,非预期的请求过大也不致于引起的系统瘫痪,系统可以拒绝或者或者引流,这就是所谓的限流。

常用限流算法

常用算法有漏桶算法和令牌桶算法

令牌桶算法:

令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。

a. 按特定的速率向令牌桶投放令牌

b.桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝;

c.当1请求到达,将从桶中删除1个令牌,接着处理请求;

d.如果桶中的令牌不足,则不会删除令牌,且该请求将被限流(要么丢弃,要么缓冲区等待)

漏桶算法:

漏桶算法的描述如下:

1.一个固定容量的漏桶,按照常量固定速率流出水滴;、

2.如果桶是空的,则不需流出水滴;

3.可以以任意速率流入水滴到漏桶;

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

实践

应用级限流:nignx中limit_conn模块,

Tomcat的Connector几种参数:

acceptCount:如果Tomcat的线程都忙于响应,新来的连接会进入队列排队,如果超出排队大小,则拒绝连接;

maxConnections:瞬时最大连接数,超出的会排队等待;

maxThreads:Tomcat能启动用来处理请求的最大线程数,如果请求处理量一直远远大于最大线程数则可能会僵死。

编程级别:

限流某个接口的总并发/请求数

=================================

try {

if(atomic.incrementAndGet() > 限流数) {

//拒绝请求

}

//处理请求

} finally {

atomic.decrementAndGet();

}

=================================

2.限流某个接口的时间窗请求数

=================================

LoadingCache counter =        CacheBuilder.newBuilder()                .expireAfterWrite(2, TimeUnit.SECONDS)                .build(newCacheLoader() {                    @OverridepublicAtomicLong load(Long seconds)throwsException {return newAtomicLong(0);                    }                });longlimit = 1000;while(true) {//得到当前秒longcurrentSeconds = System.currentTimeMillis() / 1000;if(counter.get(currentSeconds).incrementAndGet() > limit) {        System.out.println("限流了:"+ currentSeconds);continue;    }//业务处理}

3. 平滑限流某个接口的请求数(令牌桶和漏桶实践)

RateLimiter使用实践

你可能感兴趣的:(高并发之限流算法及实现)