本文參考資料
高并發(fā)系統(tǒng)之限流特技: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點負(fù)責(zé)的一個項目異常增多卦尊,服務(wù)幾近不可用,并引發(fā)雪崩熬的,造成其他項目也不可用回右。對日志進(jìn)行分析后發(fā)現(xiàn)燥翅,服務(wù)調(diào)用量激增了10倍,最后經(jīng)過擴(kuò)容解決了問題,影響時間將近20分鐘祈争。事故原因:上游系統(tǒng)一個服務(wù)站點出現(xiàn)故障站超,導(dǎo)致大量請求過來荸恕,隨后出現(xiàn)線程連接數(shù)爆滿且出現(xiàn)很多請求超時,當(dāng)調(diào)用方發(fā)現(xiàn)超時會不停的重試3次死相,這時候請求數(shù)瞬時成倍增長融求。
求索
流量激增,猶如暴雨導(dǎo)致河流流量增多算撮,可能會超過大壩的防洪庫容生宛,需要泄洪保護(hù)大壩不被沖毀;也猶如家里的保險控制肮柜,一旦使用大功率的電器陷舅,保險有可能跳閘,保護(hù)電路不被燒毀素挽。我們系統(tǒng)中如果有保險控制或防洪大壩蔑赘,非預(yù)期的請求過大也不致于引起的系統(tǒng)癱瘓,系統(tǒng)可以拒絕或者或者引流预明,這就是所謂的限流缩赛。
常用限流算法
常用算法有漏桶算法和令牌桶算法
令牌桶算法:
令牌桶算法是一個存放固定容量令牌的桶,按照固定速率往桶里添加令牌撰糠。
a. 按特定的速率向令牌桶投放令牌
b.桶中最多存放b個令牌酥馍,當(dāng)桶滿時,新添加的令牌被丟棄或拒絕阅酪;
c.當(dāng)1請求到達(dá)旨袒,將從桶中刪除1個令牌汁针,接著處理請求;
d.如果桶中的令牌不足砚尽,則不會刪除令牌施无,且該請求將被限流(要么丟棄,要么緩沖區(qū)等待)
漏桶算法:
漏桶算法的描述如下:
1.一個固定容量的漏桶必孤,按照常量固定速率流出水滴猾骡;、
2.如果桶是空的敷搪,則不需流出水滴兴想;
3.可以以任意速率流入水滴到漏桶;
4.如果流入水滴超出了桶的容量赡勘,則流入的水滴溢出了(被丟棄)嫂便,而漏桶容量是不變的。
實踐
應(yīng)用級限流:nignx中l(wèi)imit_conn模塊闸与,
Tomcat的Connector幾種參數(shù):
acceptCount:如果Tomcat的線程都忙于響應(yīng)毙替,新來的連接會進(jìn)入隊列排隊,如果超出排隊大小几迄,則拒絕連接蔚龙;
maxConnections:瞬時最大連接數(shù),超出的會排隊等待映胁;
maxThreads:Tomcat能啟動用來處理請求的最大線程數(shù)木羹,如果請求處理量一直遠(yuǎn)遠(yuǎn)大于最大線程數(shù)則可能會僵死。
編程級別:
限流某個接口的總并發(fā)/請求數(shù)
=================================
try {
if(atomic.incrementAndGet() > 限流數(shù)) {
//拒絕請求
}
//處理請求
} finally {
atomic.decrementAndGet();
}
=================================
2.限流某個接口的時間窗請求數(shù)
=================================
LoadingCache counter =??????? CacheBuilder.newBuilder()??????????????? .expireAfterWrite(2, TimeUnit.SECONDS)??????????????? .build(newCacheLoader() {??????????????????? @OverridepublicAtomicLong load(Long seconds)throwsException {return newAtomicLong(0);?????????????? ?????}??????????????? });longlimit = 1000;while(true) {//得到當(dāng)前秒longcurrentSeconds = System.currentTimeMillis() / 1000;if(counter.get(currentSeconds).incrementAndGet() > limit) {??????? System.out.println("限流了:"+ currentSeconds);continue;??? }//業(yè)務(wù)處理}
3. 平滑限流某個接口的請求數(shù)(令牌桶和漏桶實踐)