高並發服務需要關注的點


系統負載篇:

一,什么是Load Average?

系統負載(System Load)是系統CPU繁忙程度的度量,即有多少進程在等待被CPU調度(進程等待隊列的長度)。
平均負載(Load Average)是一段時間內系統的平均負載,這個一段時間一般取1分鍾、5分鍾、15分鍾。

二,如何查看Load?

1, cat /proc/loadavg

2, uptime

3, top

以上三種方式都可以查看當前系統的負載,而load average: 0.95, 0.94, 0.92 后邊這三個數字是最耐人尋味的

他們按照先后順序依次表征一分鍾,五分鍾,十五分鍾的系統平均負載(其實就是這三個時間段真正在忙碌的進程即CPU有多少個)

三, 如何評估當前系統的平均負載水平?

分割的界限:一般有經驗的系統管理員會將負載飽滿這條標准定在70%。(即忙碌的CPU占服務器總核數的百分比)

當前,我們線上服務器統統采用的是64核(vcpu)的ECS,而xadserver通過uwsgi起服務時,指定的進程數為45,讓我們來換算一下比例:45 / 64 = 0.703125

所以我們當前起服務的進程數剛剛好是略超70%標准線

我們再去線上讀一下負載水平:

1,5,15三個時段的活躍CPU大概為45,與進程數相同,所以我們服務器的負載因為我們的進程數會保持在70%左右(服務正常的前提下)

圖中負載較低的時段為每日請求數較少的時段,由圖線趨勢可知,每日晚9點至次日凌晨5點請求數持續降低,之后再持續升高,最高系統負載由服務的45個線程決定系統負載

上圖為事故當天系統負載的曲線變化

11點開始並發較高,而當時由於重啟服務的原因,slb將並發壓力分攤到其余5台機器上,導致其余5台機器系統負載升高(但並沒有超出64核的限制,所以負載升高只是服務被擊穿的表象,並不是根本原因,但可以作為佐證的一個參考依據)

服務被擊穿后,系統負載的變化曲線忽高忽低,暫無確定結果,私以為服務被擊穿后,實時處理的客戶端請求急劇降低,無法正常返回,故曲線驟降,而負載降至冰點后,大量客戶端重試請求和正常請求涌入,再次擊穿服務,如此往復導致曲線驟降驟升

 

 

TCP篇:

在Linux平台上,無論編寫客戶端程序還是服務端程序,在進行高並發TCP連接處理時,最高的並發數量都要受到系統對用戶單一進程同時可打開文件數量的限制(這是因為系統為每個TCP連接都要創建一個socket句柄,每個socket句柄同時也是一個文件句柄)。

 

對於文件句柄的數量有三層限制

1,軟限制:Linux在當前系統能夠承受的范圍內進一步限制用戶同時打開的文件數

2,硬限制:根據系統硬件資源狀況(主要是系統內存)計算出來的系統最多可同時打開的文件數量(通常軟限制小於或等於硬限制。)

3,系統限制:當前Linux系統最多允許同時打開(即包含所有用戶打開文件數總和)文件個數,是Linux系統級硬限制,所有用戶級的打開文件數限制都不應超過這個數值。通常這個系統級硬限制是Linux系統在啟動時根據系統硬件資源狀況計算出來的最佳的最大同時打開文件數限制,如果沒有特殊需要,不應該修改此限制,除非想為用戶級打開文件數限制設置超過此限制的值

軟硬限制:/etc/security/limits.conf   -→ 文件中的soft nofile/hard nofile

系統限制:cat /proc/sys/fs/file-max

當前這三個限制在我們線上機器設置的數量均為 655350

所以我們線上單台服務器理論上最高並發支持 655350(實例支持的真實最大並發與服務器的硬件配置和網絡環境有關)

事故當天單台ECS實例的TCP連接中 ESTABLISHED 數量在24000 - 25000之間,總的TCP連接數數量保持在 90000 - 100000之間,總TCP連接數-ESTABLISHED連接數=TIME_WAIT連接數 + CLOSE_WAIT連接數(其他類型的TCP狀態影響較小,暫不考慮)

處於TIME_WAIT和CLOSE_WAIT狀態的TCP連接會占用當前系統的文件句柄,影響系統的並發處理能力,而當前線上服務器對於TIME_WAIT處理的系統配置文件已經是優化過的,所以該事故的直接原因是TCP連接數超過了系統實際可承載的最大連接數

在服務正常運轉時,單台服務器的 ESTABLISHEED連接數為9000-10000,總的TCP連接數數量保持在45000 - 60000之間

 

綜上計算當前slb並發:9500 * 10 = 95000

查詢slb並發連接數,當前slb的活躍連接數與每台ECS實例的ESTABLISHED狀態TCP連接數總和數量級相同

 

監控篇:

系統負載只是線上服務出了問題之后的一種現象,而要做到提前發現就是監控ECS實例的TCP連接情況,對於不健康的TIME_WAIT以及CLOSE_WAIT提前發現(其實最終還是監控當前系統的TCP總連接數)

監控命令:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

上邊是一台線上機器的TCP連接情況,可以看到ESTABLISHED狀態的連接數目前為9000數量級,而TIME_WAIT高達40000,這是一種正常情況

因為我們的服務屬於 高並發短連接,當服務器處理完請求后會立刻主動正常關閉連接,這個場景就會出現大量socket處於TIME_WAIT狀態,而我們線上服務器已經針對此業務場景優化過系統配置

而最終造成TCP連接過多打掛服務的直接原因就是總的TCP連接數占據過多文件句柄,超出系統承受范圍。

 

所以預防線上ECS無法承受預期之外的高並發,就需要提前監控ECS的當前TCP總連接數,設置閾值,提前報警。

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com