服務器高并發(fā)(一)
- 作者:新網(wǎng)
- 來源:新網(wǎng)
- 瀏覽:100
- 2018-05-10 17:53:06
在網(wǎng)上購物秒搶某個商品,比如說小米手機,這對我們來說都不陌生。這些看似很簡單的東西從技術的角度來說對于Web系統(tǒng)是一個巨大的考驗,一個Web系統(tǒng)在很短時間內(nèi)收到很多請求時,系統(tǒng)的優(yōu)化和穩(wěn)定至關重要。今天就由小編為大家詳細解釋一下這些問題。
在網(wǎng)上購物秒搶某個商品,比如說小米手機,這對我們來說都不陌生。這些看似很簡單的東西從技術的角度來說對于Web系統(tǒng)是一個巨大的考驗,一個Web系統(tǒng)在很短時間內(nèi)收到很多請求時,系統(tǒng)的優(yōu)化和穩(wěn)定至關重要。今天就由小編為大家詳細解釋一下這些問題。
<
div>
1、大規(guī)模并發(fā)帶來的挑戰(zhàn)
比如說5w每秒的高并發(fā)秒殺功能,在這個過程中,整個Web系統(tǒng)遇到了很多的問題和挑戰(zhàn)。如果Web系統(tǒng)不做針對性的優(yōu)化,會輕而易舉地陷入到異常狀態(tài)。一起來討論下優(yōu)化的思路和方法。
1.1、請求接口的合理設計
一個搶購頁面,通常分為2個部分,一個是靜態(tài)的HTML等內(nèi)容,另一個就是Web后臺請求接口。通常靜態(tài)HTML等內(nèi)容,是通過CDN的部署,一般壓力不大,核心瓶頸實際上在后臺請求接口上。這個后端接口,必須能夠支持高并發(fā)請求,同時必須盡可能“快”,在最短的時間里返回用戶的請求結果。為了實現(xiàn)盡可能快這一點,接口的后端存儲使用內(nèi)存級別的操作會更好一點,仍然直接面向MySQL之類
數(shù)據(jù)庫的存儲是不合適的,如果有這種復雜業(yè)務的需求,都建議采用異步寫入。
1.2、高并發(fā)的挑戰(zhàn)
衡量一個Web系統(tǒng)的吞吐率的指標是QPS(Query Per Second,每秒處理請求數(shù)),解決每秒數(shù)萬次的高并發(fā)場景,這個指標非常關鍵。假設處理一個業(yè)務請求平均響應時間為100ms,同時系統(tǒng)內(nèi)有20臺Apache的Web
服務器,配置MaxClients為500個(表示Apache的最大連接數(shù)目)。那么Web系統(tǒng)的理論峰值QPS為(理想化的計算方式):20*500/0.1 = 100000 (10萬QPS) ,系統(tǒng)似乎很強大,1秒鐘可以處理完10萬的請求,實際情況當然沒有這么理想。在高并發(fā)的實際場景下,機器都處于高負載的狀態(tài),在這個時候平均響應時間會被大大增加。就Web服務器而言,Apache打開了越多的連接進程,CPU需要處理的上下文切換也越多,額外增加了CPU的消耗,然后就直接導致平均響應時間增加。因此上述的MaxClient數(shù)目,要根據(jù)CPU、內(nèi)存等硬件因素綜合考慮,絕對不是越多越好??梢酝ㄟ^Apache自帶的abench來測試一下,取一個合適的值。然后,我們選擇內(nèi)存操作級別的存儲的Redis,在高并發(fā)的狀態(tài)下,存儲的響應時間至關重要,不考慮網(wǎng)絡帶寬和
負載均衡問題。假設系統(tǒng),在5w/s的高并發(fā)狀態(tài)下,平均響應時間從100ms變?yōu)?50ms(實際情況,甚至更多):20*500/0.25 = 40000 (4萬QPS)于是系統(tǒng)剩下了4w的QPS,面對5w每秒的請求,中間相差了1w。 舉個通俗例子說明,收費站1秒鐘來5部車,每秒通過5部車,收費站運作正常。突然這個收費站1秒鐘只能通過4部車,車流量仍然依舊,結果必定出現(xiàn)大塞車。(5條車道忽然變成4條車道的感覺)同理某一個秒內(nèi),20*500個可用連接進程都在滿負荷工作中,卻仍然有1萬個新來請求,沒有連接進程可用,系統(tǒng)陷入到異常狀態(tài)也是預期之內(nèi)。其實在正常的非高并發(fā)的業(yè)務場景中,也有類似的情況出現(xiàn),某個業(yè)務請求接口出現(xiàn)問題,響應時間極慢,將整個Web請求響應時間拉得很長,逐漸將Web服務器的可用連接數(shù)占滿,影響其他正常的業(yè)務請求,無連接進程可用。更嚴重的是用戶的行為,系統(tǒng)越是不可用,用戶的點擊越頻繁,惡性循環(huán)最終導致“雪崩”(其中一臺Web機器掛了,導致流量分散到其他正常工作的機器上,再導致正常的機器也掛,然后惡性循環(huán)),將整個Web系統(tǒng)拖垮。
1.3、重啟與過載保護
如果系統(tǒng)發(fā)生“雪崩”,貿(mào)然重啟服務,是無法解決問題的。這種情況最好在入口層將流量拒絕,然后再將重啟,如果是redis/memcache這種服務也掛了,重啟的時候需要注意“預熱”,并且很可能需要比較長的時間。秒殺和搶購的場景,流量往往是超乎系統(tǒng)的準備和想象的。這個時候過載保護是必要的。如果檢測到系統(tǒng)滿負載狀態(tài),拒絕請求也是一種保護措施。在前端設置過濾是最簡單的方式,但是,這種做法是會被客戶罵的,更合適的
解決方案是將過載保護設置在CGI入口層,快速將客戶的直接請求返回。