1. 程式人生 > >高並發解決方案

高並發解決方案

高並發解決方案

一、什麽是高並發

高並發(High Concurrency)是互聯網分布式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時並行處理很多請求。高並發相關常用的一些指標有響應時間(Response Time),吞吐量(Throughput),每秒查詢率QPS(Query Per Second),並發用戶數等。

響應時間:系統對請求做出響應的時間。例如系統處理一個HTTP請求需要200ms,這個200ms就是系統的響應時間。

吞吐量:單位時間內處理的請求數量。

QPS:每秒響應請求數。在互聯網領域,這個指標和吞吐量區分的沒有這麽明顯。

並發用戶數:同時承載正常使用系統功能的用戶數量。例如一個即時通訊系統,同時在線量一定程度上代表了系統的並發用戶數。

二、什麽是秒殺

秒殺場景一般會在電商網站舉行一些活動或者節假日在12306網站上搶票時遇到。對於電商網站中一些稀缺或者特價商品,電商網站一般會在約定時間點對其進行限量銷售,因為這些商品的特殊性,會吸引大量用戶前來搶購,並且會在約定的時間點同時在秒殺頁面進行搶購。

此種場景就是非常有特點的高並發場景,如果不對流量進行合理管控,肆意放任大流量沖擊系統,那麽將導致一系列的問題出現,比如一些可用的連接資源被耗盡、分布式緩存的容量被撐爆、數據庫吞吐量降低,最終必然會導致系統產生雪崩效應。

一般來說,大型互聯網站通常采用的做法是通過擴容、動靜分離、緩存、服務降級及限流五種常規手段來保護系統的穩定運行。

三、擴容

由於單臺服務器的處理能力有限,因此當一臺服務器的處理能力接近或已超出其容量上限時,采用集群技術對服務器進行擴容,可以很好地提升系統整體的並行處理能力,在集群環境中,節點的數量越多,系統的並行能力和容錯性就越強。           

在無狀態服務下,擴容可能是迄今為止效果最明顯的增加並發量的技巧之一。

從擴容方式角度講,分為垂直擴容(scale up)和水平擴容(scale out)。垂直擴容就是增加單機處理能力,懟硬件,但硬件能力畢竟還是有限;水平擴容說白了就是增加機器數量,懟機器,但隨著機器數量的增加,單應用並發能力並不一定與其呈現線性關系, 此時就可能需要進行應用服務化拆分了。

從數據角度講,擴容可以分為無狀態擴容和有狀態擴容。無狀態擴容一般就是指我們的應用服務器擴容;有狀態擴容一般是指數據存儲擴容,要麽將一份數據拆分成不同的多份,即sharding,要麽就整體復制n份,即副本。sharding遇到的問題就是分片的可靠性,一般做轉移、rehash、分片副本;副本遇到的問題是一致性性,一般做一致性算法,如paxos,raft等。

四、動靜分離

動靜分離,靜態資源請求與動態請求分離,項目中需要訪問的圖片、聲音、js/css等靜態資源需要有獨立的存放位置,便於將來實現靜態請求分離時直接剝離出來,比如nginx可以直接配置圖片文件直接訪問目錄,而不需要經過tomcat。這樣tomcat就可以專註處理動態請求,操作數據庫數據處理之類的。靜態請求代理服務器性能比tomcat高很多。

動靜分離是指,靜態頁面與動態頁面分開不同系統訪問的架構設計方法。

技術分享圖片

一般來說:

  • 靜態頁面訪問路徑短,訪問速度快,幾毫秒
  • 動態頁面訪問路徑長,訪問速度相對較慢(數據庫的訪問,網絡傳輸,業務邏輯計算),幾十毫秒甚至幾百毫秒,對架構擴展性的要求更高
  • 靜態頁面與動態頁面以不同域名區分

系統需要將動態數據 和靜態數據分而治之,用戶對靜態數據的訪問,應該避免請求直接落到企業的數據中心,而是應該在CDN中獲取,以加速系統的響應速度。

技術分享圖片

五、緩存

緩存之所以能夠提高處理速度,是因為不同設備的訪問速度存在差異。緩存的話題可以扯幾本書不帶重樣的。從CPU可以一直扯到客戶端緩存,即從最底層一直到扯到最特近用戶的一層,每一層都可能或可以有緩存的存在。我們這裏不扯這麽多,只說簡單服務端緩存。現在從幾個不同角度來看一下緩存:

①從效果角度。命中率越高越好嗎?10萬個店鋪數據,緩存了1000個,命中率穩定100%,那是不是說,有99000個店鋪都是長尾店鋪?緩存效果評估不能單看命中率。

②從回收策略。如果把緩存當做數據庫一樣的存儲設備去用,那就沒有回收的說法了(除非重啟或者宕機,否則數據依然有效);如果只存儲熱數據,那就有回收和替換的問題。回收有兩種方式,一種是空間配額,另一種是時間配額。替換也有幾種方式,LRU,FIFO,LFU。

③從緩存使用模式角度:用戶直接操作緩存和db;用戶直接操作緩存,緩存幫助我們讀寫DbB;

④從緩存分級角度。java堆內緩存、java堆外緩存、磁盤緩存、分布式緩存,多級緩存。

⑤從緩存使用角度。null穿透問題、驚群問題、緩存熱點問題、緩存一致性問題、讀寫擴散問題。。。。。。

⑥更新方式。讀更新、寫更新、異步更新。

如果緩存集群涉及到異地多集群部署,再結合大數據量高並發業務場景,還會遇到很多更加復雜的問題,這裏就不一一列舉了。

六、服務降級

業務高峰期,為了保證核心服務,需要停掉一些不太重要的業務,eg 商品評論、論壇或者粉絲積分等

另外一些場景就是某些服務不可用時,又不能直接讓整個流程失敗就本地Mcok(模擬)實現,做流程放通

eg 用戶登錄余額鑒權服務不能正常工作,需要做業務放通,記錄消費話單允許用戶繼續訪問,而不是返回失敗

為了保證以上兩種場景的正常服務,服務需要有降級。

服務降級主要包括容錯降級和屏蔽降級

屏蔽降級:

1)throw null 不發起遠程調用,直接返回空

2)throw exception 不發起遠程調用,直接拋出指定異常

3)execute bean 不發起遠程調用,直接執行本地模擬接口實現

服務降級是可逆操作,當系統壓力恢復到一定值不需要降級服務時,要重新發起遠程調用,服務狀態改為正常

容錯降級:

非核心服務不可調用時,可以對故障服務做業務放通,保證主流程不受影響

1)RPC異常:通常指超時、消息解碼異常、流控異常、系統擁塞保護異常等

2)Service異常 eg登錄校驗異常、數據庫操作失敗異常等

七、限流

通過對並發訪問和請求進行限速或者一個時間窗口內的請求進行限速來保護系統的可用性,一旦達到限制速率就可以拒絕服務(友好定向到錯誤頁或告知資源沒有了),排隊或者等待(比如秒殺,評論,下單),降級(返回默認數據)。

通過壓測的手段找到每個系統的處理峰值,然後通過設定峰值閾值,來防止當系統過載時,通過拒絕處理過載的請求來保障系統 可用性,同時也應該根據系統的吞吐量,響應時間,可用率來動態調整限流閾值。

分類:

  • 限制總並發數---數據庫連接池,線程池
  • 限制瞬時並發數---nginx的limit_conn模塊,用來限制瞬時並發連接數
  • 限制時間窗口內的平均速率---guava的RateLimiter,nginx的limit_req模塊,限制每秒平均速率
  • 其他---限制遠程接口調用速率,限制MQ消費速率,另外,還可以根據網絡連接數,網絡流量,CPU或內存負載等來限流。

算法:

  • 滑動窗口協議---改善吞吐量的技術
  • 漏桶---強制限制數據的傳輸速率,限制的流出速率
  • 令牌桶---(控制(流入)速率類型的限流算法)系統以恒定的速度往桶中放入令牌,如果請求需要被處理,則需要先從桶中獲取一個令牌,當桶中沒有令牌可取,則拒絕服務。當平時處理速率小於桶中令牌的速率,那麽在突發流量時桶內有堆積可以有效預防。

令牌桶

技術分享圖片

漏桶

技術分享圖片

八、總結

任何一個分布式系統的容量都會存在上限,哪怕天貓這種級別的網站也不例外。一旦用戶流量過載,系統的吞吐量便會開始下降,RT線上升,最終導致系統容量被撐爆而出現雪崩效應。因此,架構師在對系統架構進行設計時,一定要考慮到系統整個鏈路的各個環節。上述介紹的五種手段,看似平淡無奇,但是組合在一起卻能爆發出驚人的力量。根據自己所處的場景,嘗試各個方式進行解決,找到最適合的。

高並發解決方案