海量數(shù)據(jù)處理之系統(tǒng)過(guò)載保護(hù)
前段時(shí)間在網(wǎng)上看到騰訊后臺(tái)開(kāi)發(fā)總監(jiān)bison分享的一篇文章《淺談過(guò)載保護(hù)》,讀來(lái)受益匪淺。剛好自己也在處理系統(tǒng)請(qǐng)求過(guò)載的問(wèn)題,把自己的一些心得體會(huì)總結(jié)出來(lái)拿來(lái)與大家一起探討。
在bison的文章中談到:對(duì)于延時(shí)敏感的服務(wù),當(dāng)外部請(qǐng)求超過(guò)系統(tǒng)處理能力,如果系統(tǒng)沒(méi)有做相應(yīng)保護(hù),可能導(dǎo)致歷史累計(jì)的超時(shí)請(qǐng)求達(dá)到一定的規(guī)模,像雪球一樣形成惡性循環(huán),由于系統(tǒng)處理的每個(gè)請(qǐng)求都因?yàn)槌瑫r(shí)而無(wú)效,系統(tǒng)對(duì)外呈現(xiàn)的服務(wù)能力為0,且這種情況不能自動(dòng)恢復(fù)。我們的系統(tǒng)就是要盡量避免這種情況的出現(xiàn),下面將詳細(xì)來(lái)分析一個(gè)現(xiàn)實(shí)中的案例。
一 有過(guò)載問(wèn)題的系統(tǒng)
 
數(shù)據(jù)處理流程:
1) 前端將請(qǐng)求發(fā)送給數(shù)據(jù)解析及轉(zhuǎn)發(fā)系統(tǒng),
2)數(shù)據(jù)解析及轉(zhuǎn)發(fā)系統(tǒng)將封裝好的數(shù)據(jù)發(fā)送后臺(tái)數(shù)據(jù)請(qǐng)求,設(shè)置超時(shí)時(shí)間(假設(shè)300ms),線程同步等待處理結(jié)果從后臺(tái)返回。
3)在300ms內(nèi)正確返回結(jié)果后,則將處理的結(jié)果返回給前端,如果在300ms內(nèi)超時(shí),則將數(shù)據(jù)發(fā)送到一次超時(shí)處理系統(tǒng)(假設(shè)設(shè)置超時(shí)時(shí)間500ms),線程同步等待結(jié)果返回。
4)在500ms內(nèi)正確返回結(jié)果后,則將處理的結(jié)果返回給前端,如果再一次超時(shí),返回一個(gè)默認(rèn)的處理結(jié)果給前端,后端對(duì)數(shù)據(jù)進(jìn)行本地化,然后可以將數(shù)據(jù)發(fā)送到離線處理系統(tǒng)進(jìn)行二次處理。
數(shù)據(jù)解析的機(jī)器為多核,數(shù)據(jù)解析及轉(zhuǎn)發(fā)系統(tǒng)采用的是單進(jìn)程多線程模型,在前一篇文章《海量數(shù)據(jù)處理系列之Java線程池使用》詳細(xì)描述了多線程處理的實(shí)現(xiàn),采取的是無(wú)界隊(duì)列線程池的實(shí)現(xiàn),這樣從客戶(hù)端來(lái)的請(qǐng)求,會(huì)被這樣處理:
1) 如果線程池中有空閑線程,會(huì)將請(qǐng)求直接交給線程處理。
2) 如果沒(méi)有空閑線程,就將請(qǐng)求保存到任務(wù)隊(duì)列。
假設(shè)開(kāi)50個(gè)線程,每個(gè)線程秒平均處理一個(gè)請(qǐng)求,那么系統(tǒng)每秒可以處理的最大請(qǐng)求數(shù)是50個(gè)。一旦前端數(shù)據(jù)請(qǐng)求超過(guò)50個(gè)每秒,在任務(wù)隊(duì)列中將會(huì)堆積大量的請(qǐng)求,前臺(tái)不斷發(fā)送過(guò)來(lái),后來(lái)處理不過(guò)來(lái),前端又設(shè)置了套接字超時(shí),導(dǎo)致隊(duì)列中的大量請(qǐng)求超時(shí),直接使得后端線程從隊(duì)列中取出套接字解析的時(shí)候,套接字已經(jīng)被前臺(tái)關(guān)閉了,引發(fā)I/O異常。堆積的量一旦雪崩,將使前臺(tái)發(fā)送過(guò)來(lái)的請(qǐng)求全部I/O異常,后臺(tái)處理系統(tǒng)跟掛掉無(wú)異了。
二 相對(duì)完善的系統(tǒng)

在上面的系統(tǒng)中,對(duì)請(qǐng)求是來(lái)者不拒的狀態(tài),具體來(lái)講就是將所有的請(qǐng)求都保存到任務(wù)隊(duì)列。請(qǐng)求堆積到一定程度,隊(duì)列中的很多請(qǐng)求都超時(shí),這是可以采取清空請(qǐng)求隊(duì)列的方式,這個(gè)可以通過(guò)采取一定的監(jiān)控方式來(lái)實(shí)現(xiàn)。例如上圖中的心跳監(jiān)控模塊,它可以通過(guò)這樣的方式來(lái)實(shí)現(xiàn),就是模擬客戶(hù)端的請(qǐng)求,每隔一定時(shí)間發(fā)送一些請(qǐng)求過(guò)去,如果有大部分都正常返回,說(shuō)明后端處理系統(tǒng)正常;當(dāng)出現(xiàn)大部分超時(shí)的時(shí)候,說(shuō)明后臺(tái)系統(tǒng)已經(jīng)掛掉了,這時(shí)候重啟數(shù)據(jù)解析及轉(zhuǎn)發(fā)系統(tǒng),清空系統(tǒng)中的任務(wù)請(qǐng)求隊(duì)列,這樣可以暫時(shí)處理請(qǐng)求高峰期的情況。
但是這個(gè)方式也是治標(biāo)不治本的,后臺(tái)最多只能處理這么多請(qǐng)求,重啟后照樣會(huì)導(dǎo)致大量堵塞導(dǎo)致系統(tǒng)又掛掉,然后監(jiān)控系統(tǒng)又重啟,這樣會(huì)使得很多的請(qǐng)求沒(méi)有得到有效的處理,大大降低系統(tǒng)的處理能力。為了保證后臺(tái)系統(tǒng)每時(shí)每刻都最大限度的發(fā)揮自己的處理能力,當(dāng)負(fù)載超過(guò)系統(tǒng)自身的處理能力時(shí),拒絕該請(qǐng)求。拒絕后可以將該請(qǐng)求本地系列化,保存相關(guān)的數(shù)據(jù)發(fā)送到離線數(shù)據(jù)處理系統(tǒng)進(jìn)行處理。
在前一篇文章《海量數(shù)據(jù)處理系列之Java線程池使用》第四節(jié)中有界隊(duì)列線程池使用中有提到這種方式的具體實(shí)現(xiàn)。以上面的系統(tǒng)為例,有界線程池可以這樣配置,corePoolSize為30,maximumPoolSize為50,有界隊(duì)列為ArrayBlockingQueue<Runnable>(100)。這樣系統(tǒng)在處理請(qǐng)求的時(shí)候采用如下策略:
1) 當(dāng)一個(gè)請(qǐng)求過(guò)來(lái),線程池開(kāi)啟一個(gè)線程來(lái)處理,直到30個(gè)線程都在處理請(qǐng)求。
2) 當(dāng)線程池中沒(méi)有空閑線程了,就將請(qǐng)求添加到有界隊(duì)列當(dāng)中,直到隊(duì)列滿(mǎn)為止。
3) 當(dāng)隊(duì)列滿(mǎn)以后,在開(kāi)啟線程來(lái)處理新的請(qǐng)求,直到開(kāi)啟的線程數(shù)達(dá)到maximumPoolSize。
4) 當(dāng)開(kāi)啟的線程數(shù)達(dá)到maximumPoolSize后,任務(wù)隊(duì)列又已經(jīng)滿(mǎn)了后,此時(shí)再過(guò)來(lái)的請(qǐng)求將被拒絕,被拒絕的請(qǐng)求在本地系列化,將保存的數(shù)據(jù)同步到離線數(shù)據(jù)系統(tǒng)進(jìn)行處理。
海量數(shù)據(jù)處理都是采用分布式的,每臺(tái)機(jī)器的處理能力有限,可以將請(qǐng)求分布到不同的機(jī)器上去。如果每臺(tái)機(jī)器被拒絕的請(qǐng)求數(shù)過(guò)多的時(shí)候,就要考慮添加處理的機(jī)器了。
原文鏈接:http://www.cnblogs.com/cstar/archive/2012/06/25/2561388.html
【編輯推薦】
- 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之開(kāi)卷有益
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模1
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模2
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模3
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模4
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)設(shè)計(jì)規(guī)范與原則1
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)設(shè)計(jì)規(guī)范與原則2
 - 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之業(yè)務(wù)邏輯層
 















 
 
 









 
 
 
 