A. 阿里雲ECS的CPU100%排查
一、背景和現象
初創公司,架構lanmp,web前端和後端分開伺服器,業務驅動主要是nginx和apache,nginx主要是處理靜態文件和反向代理,前後端、搜索引擎、緩存、隊列等附加的服務都是用docker容器部署。因為比較初級,上傳文件和採集文件都是直接寫在硬碟上,涉及到的目錄共享,就在其中一台伺服器存儲並且nfs共享。我們暫且分為ECS1(apache1)、ECS2(apache2)、ECS3(nginx)。某天網站業務中斷,但是沒有報錯。一直在等待響應,默認響應超時是一分鍾,所以很基礎高可用沒有起到作用。中斷10分鍾左右,重啟服務,提示「open too many files」,但是lsof統計沒幾個。因為初級處理不了,所以直接重啟伺服器,一段時間後一切恢復正常,可是第二天又來一次這種情況。
二、第一次出現後的排查思路
本來第一次發現這種問題的時候就要追查原因了,看了一下zabbix監控圖像其中斷了十分鍾,包括網路、內存、CPU、硬碟、IO等監控數據。首先想到的是網路問題,結論是zabbix-servert獲取不到了zabbix-agent採集的數據,估計就是網路不通了。
但是,這個結論站不住腳,因為我本身通過ssh登錄伺服器,並且命令輸入無卡頓,不至於頭文件都傳不過來。後來一看阿里雲的雲監控,上面有數據,似乎也可以佐證網路這個說法,因為雲監控是阿里雲內部的監控,可以內網獲取到監控數據。直到看CPU的使用率這項,發現有一段時間的CPU使用率100%。並且我重啟的時候CPU恢復正常,不能說網路一定沒問題,但系統肯定有問題。也可以解釋因為CPU使用已經是100%,zabbix-agent和根本不能正常運行,所以沒有監控數據。因為這個公司全部都是雲伺服器,沒有使用IDC所以我們也沒有安裝smokeping來監控,接著我們就不把重心在網路上了。
目前掌握的信息就是:在毫無徵兆的情況下,CPU暴漲到100%,重啟之前一直保留,重啟之後恢復原樣。匆忙之中又看了一下系統各日誌,因為太匆忙,沒有總結,沒有找到什麼有價值的東西。現在有下面幾種猜想:第一,程序的bug或者部署不當,觸發之後耗盡資源。第二、docker容器的bug。第三、網路攻擊。第四、病毒入侵。第五、阿里雲方系統不穩定。
小總結了一下,現在問題還沒有找出來。下次還有這個問題的可能,所以先盡量防範,但是又不能重啟一刀切。所以在zabbix上面設置了自動化,當檢測到ECS1獲取不到數據的時候馬上操作ECS3標記後端為ECS1的apache為down。保留異常現場。(請求停止的時候,CPU100%還在)
三、現場排查
1、相應的排查計劃(想到這些信息需要獲取的,實際上沒有嚴格按照這樣的步驟)
1)用htop和top命令監控CPU、內存使用大的進程。先看看哪個進程消耗資源較多,用戶態、內核態、內存、IO……同時sar -b查io的 歷史 定時抽樣。
2)統計tcp連接數,看看有沒有DDOS攻擊。netstat -anp |grep tcp |wc -l 。用iftop-i eth1看看通訊。同時用tail -n 1200 /var/log/messages查看內核日誌。
3)用pstree查看打開進程,ps aux|wc-l看看有沒有特別多的進程。雖然zabbix監控上說沒有,但是我們要檢查一下看看有沒有異常的進程名字。
4)查看全部容器的資源使用docker stats $(docker ps -a -q),看看能不能從容器上排查。
5)有了「too many open files」的啟發,計算打開文件數目lsof|wc -l,根據進程看看ll /proc/PID/fd文件描述符有沒有可疑的打開文件、文件描述符。
6)關於用lsof打開文件數找到的線索,排序打開文件找出進程號 lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more
7)關於用lsof打開文件數找到的線索,用lsof -p PID查看進程打開的句柄。直接查看打開的文件。
8)啟動容器的時候又總是「open too many files"。那就是打開文件數的問題,因為CPU的使用率是CPU的使用時間和空閑時間比,有可能因為打開文件數阻塞而導致CPU都在等待。針對連接數的問題,大不了最後一步試試echo 6553500 > /proc/sys/fs/file-max 測試打開文件對CPU的影響。
9)玩意測出來了消耗CPU的進程,可以使用strace最終程序。用戶態的函數調用跟蹤用「ltrace」,所以這里我們應該用「strace」-p PID
10)從程序裡面看到調用系統底層的函數可以跟蹤。跟蹤操作 strace -T -e * -p PID,主要看看代碼調用的函數有沒有問題。
2、現場排查
第二天同樣時間,ECS果然暴漲了CPU。這是時候zabbix的工作如希望進行保留了一台故障的ECS1給我。
1)用htop看到資源使用最大是,搜索引擎下我寫的一個判斷腳本xunsearch.sh。腳本裡面很簡單,判斷索引和搜索服務缺一個就全部重啟。就當是我的容器有問題我直接關掉搜索引擎容器。httpd頂上,我又關掉apache容器。rabbitmq相關進程又頂上。這時候我沒心情周旋了,肯定不也是這個原因。sar -b查看的 歷史 io也沒有異常。
2)統計tcp連接,幾百。先不用著重考慮攻擊了。用tail -n 1200 /var/log/messages查看內核日誌,是TCP TIME WAIT的錯誤。可以理解為CPU使用100%,程序無響應外面的tcp請求超時。這是結果,還是沒有找到根本原因。
接著往下看系統內核日誌,發現了和「open too many files」呼應的錯誤,「file-max limit 65535 reached」意思是,已到達了文件限制瓶頸。這里保持懷疑,繼續收集其他信息。
3)查看進程數量,數量幾百。列出來也看到都是熟悉的進程,可以先排除異常進程。
4)監控容器的資源使用,裡面很不穩定,首先是xunsearch容器使用80%的CPU,關掉xunsearch,又變成了其他容器使用CPU最高。很大程度上可以排查容器的問題和執行程序的問題。
5)查看了最大連接數cat /proc/sys/fs/file-max是65535但是用lsof查到的連接數是10000多,完全沒有達到連接數。
6)各項參數都正常,現在聚焦在打開的文件數這個問題上面。也可以用另外同一種方式查看一下內核統計文件 /proc/sys/fs/file-nr,比較一下差異,看看能不能找出問題。cat了一下,打開文件數是66080,果然超了!內核日誌就以這個為標准。
但是看lsof怎麼統計不出來,ll /proc/PID/fd也沒幾個。這個問題放在後面,先按照步驟echo 6553500 > /proc/sys/fs/file-max給連接數提高到100倍,CPU果然降了下來。原因確認了,但是必須找到根源,為什麼忽然有這么大的打開文件數。關掉全部docker容器和docker引擎,打開文件數是少了一點,但是仍然在65535差不多。我就先排除一下業務的影響,把ECS3的nginx直接指向視頻ECS2的apache,就等同於在ECS2上實現了ECS1的場景。查看一下ECS2的句柄數,才4000多,排除了業務相關應用對伺服器的影響。那就能下個小結論,ECS1被神秘程序打開了6萬多句柄數,打開業務就多了2000多的句柄數,然後就崩潰了。不過這個現象有點奇怪,ECS2和ECS1在一樣的機房一樣的配置一樣的網路環境,一樣的操作系統,一樣的服務,一樣的容器,為什麼一個有問題,一個沒問題呢?不同的只是有一台是共享nfs。難道是靜態文件共享了,其他人讀了,也算是本伺服器打開的?
7)現在程序找不到,沒法繼續lsof -p了。排查之前的猜想。帶著排查得到對的結論往下想。
程序的bug和部署不當,那是不可能的,因為主要問題來自於打開句柄數,當部署到ECS2那裡,一切正常。docker容器的bug,那也不可能的,每個都是我親自寫腳本,親自編譯,親自構建的,關鍵是我關掉了docker容器和引擎都沒有很大改善。網路攻擊也排除,因為網路連接數沒幾個,流量也不變。那就只剩下病毒入侵也不是,沒有異常進程。考慮到ECS的穩定性問題了。這方面就協助阿里雲工程師去排查。
8)阿里雲工程師用的排查手段和我差不多,最終也是沒能看到什麼。也只是給了我一些治標不治本的建議。後來上升到專家排查,專家直接在阿里雲後端抓取了coremp文件分析打開的文件是圖片,程序是nfsd。
好像印證了我剛才後面的猜想,應該就是ECS1使用了nfs共享其他伺服器打開瞭然後算在ECS1頭上。那問題又來了,我們的業務已經到達了可以影響伺服器的程度嗎?
9)既然問題解決到這一步,先不管程序有沒有關閉打開的文件和nfs的配置。我們架構上面的圖片應該是歸nginx讀取,難道是linux的內存機制讓它緩存了。帶著緩存的問題,首先去ECS3上釋放內存echo 3 > /proc/sys/vm/drop_caches,釋放之後,發現沒什麼改善,有點失落。總是覺得還有一台後端是PHP主導,但是邏輯上是寫入,沒有打開文件之說。後來從程序員中了解到,PHP也有打開圖片。我猛然去ECS2釋放一下內存,果然,句柄數降下來。(這里大家一定有個疑問,為什麼我直接想到內存緩存而不是目前打開的文件呢。其一,這是生產環境,web前端只有一個,不能亂來停服務。其二,第一次遇到問題的時候,重啟之後沒有問題,過了一天之後積累到一定的程度才爆發,這里已經引導了我的思路是積累的問題,那就是緩存不斷積累了)
10)因為ECS2的調用ECS1的nfs共享文件,所以lsof也有讀不到那麼多句柄數的理由。如果說是nfs的服務本身就有緩存,導致問題的話,我查看了配置文件,還是默認值允許緩存,30S過期,根本不會因為nfs的緩存造成打開文件過多。如果我們的後端程序打開之後沒好好處理的話,那倒有可能。然後嘗試排除:我改了ECS3的配置,使程序只讀ECS1後端,從ECS1上面卻看不到有什麼異常表現,說明PHP程序已經好好處理了打開的文件。也不是docker掛載了nfs的共享的問題,因為nginx也有掛載。排查到這里也很大程度上解決問題,而且緩存了nfs的全部共享文件,句柄並沒有增加,也算合理,所以就增加了打開文件數的限制。
11)現在排查的結果是跟後端和nfs共享有關。就是說,後端掛載了nfs的網路共享,被程序讀取。而程序釋放之後,在正常背景的硬碟文件是沒有緩存的。但是在nfs掛載的環境下,緩存並沒有得到釋放。
12)總結:很多問題的排查和我們的猜想結果一樣,但是有些例外的情況。比如這次我想到的原因都一一排除,但是問題也是在一步步排查中,逐步被發現的。
B. 阿里雲虛擬主機的內存和CPU一直高居不下,網站訪問變慢
這一般是程序設計問題,沒有及時釋放 資源。。
C. 阿里雲伺服器的cup佔用不高,都是系統操作很卡是什麼原因(主要是進入伺服器的目錄都很卡)
檢查下硬碟讀寫的IO是不是達到瓶頸 或伺服器里有無大量的讀寫操作,如果沒有的話那就要檢查下伺服器是否中了挖礦木馬了
D. 阿里雲ECS伺服器CPU佔用較高時,該如何處理
這種情況可以考慮是被挖礦了,可以找到雲市場雲頂雲尋求幫助,一般這種情況會讓工程師進行排查找出問題所在,然後再進行修理,大概的時間一般是三天以內
E. 阿里雲伺服器cpu跑滿怎麼解決
找出是哪個進程在消耗CPU,如果覺得麻煩,直接加CPU。
F. 阿里雲cpu檢測進程mysql太高怎麼解決
一台伺服器解決了 Mysql cpu 佔用 100% 的問題。稍整理了一下,將經驗記錄在這篇文章里。
朋友主機(Windows 2003 + IIS + PHP + MYSQL )近來 MySQL 服務進程 (mysqld-nt.exe) CPU 佔用率總為 100% 高居不下。此主機有10個左右的 database, 分別給十個網站調用。據朋友測試,導致 mysqld-nt.exe cpu 佔用奇高的是網站A,一旦在 IIS 中將此網站停止服務,CPU 佔用就降下來了。一啟用,則馬上上升。
MYSQL CPU 佔用 100% 的解決過程
今天早上仔細檢查了一下。目前此網站的七日平均日 IP 為2000,PageView 為 3萬左右。網站A 用的 database 目前有39個表,記錄數 60.1萬條,占空間 45MB。按這個數據,MySQL 不可能佔用這么高的資源。於是在伺服器上運行命令,將 mysql 當前的環境變數輸出到文件 output.txt:
d:\web\mysql> mysqld.exe --help >output.txt發現 tmp_table_size 的值是默認的 32M,於是修改 My.ini, 將 tmp_table_size 賦值到 200M:
d:\web\mysql> notepad c:\windows\my.ini
[mysqld]
tmp_table_size=200M
然後重啟 MySQL 服務。CPU 佔用有輕微下降,以前的CPU 佔用波形圖是 100% 一根直線,現在則在 97%~100%之間起伏。這表明調整 tmp_table_size 參數對 MYSQL 性能提升有改善作用。但問題還沒有完全解決。
於是進入 mysql 的 shell 命令行,調用 show processlist, 查看當前 mysql 使用頻繁的 sql 語句:
mysql> show processlist;
反復調用此命令,發現網站 A 的兩個 SQL 語句經常在 process list 中出現,其語法如下:
SELECT t1.pid, t2.userid, t3.count, t1.dateFROM _mydata AS t1
LEFT JOIN _myuser AS t3 ON t1.userid=t3.useridLEFT JOIN _mydata_body AS t2 ON t1.pid=t3.pidORDER BY t1.pid
LIMIT 0,15
調用 show columns 檢查這三個表的結構 :
mysql> show columns from _myuser;
mysql> show columns from _mydata;
mysql> show columns from _mydata_body;
終於發現了問題所在:_mydata 表,只根據 pid 建立了一個 primary key,但並沒有為 userid 建立索引。而在這個 SQL 語句的第一個 LEFT JOIN ON 子句中:
LEFT JOIN _myuser AS t3 ON t1.userid=t3.userid_mydata 的 userid 被參與了條件比較運算。於是我為給 _mydata 表根據欄位 userid 建立了一個索引:
mysql> ALTER TABLE `_mydata` ADD INDEX ( `userid` )建立此索引之後,CPU 馬上降到了 80% 左右。看到找到了問題所在,於是檢查另一個反復出現在 show processlist 中的 sql 語句:
SELECT COUNT(*)
FROM _mydata AS t1, _mydata_key AS t2
WHERE t1.pid=t2.pid and t2.keywords = '孔雀'
經檢查 _mydata_key 表的結構,發現它只為 pid 建了了 primary key, 沒有為 keywords 建立 index。_mydata_key 目前有 33 萬條記錄,在沒有索引的情況下對33萬條記錄進行文本檢索匹配,不耗費大量的 cpu 時間才怪。看來就是針對這個表的檢索出問題了。於是同樣為 _mydata_key 表根據欄位 keywords 加上索引:
mysql> ALTER TABLE `_mydata_key` ADD INDEX ( `keywords` )建立此索引之後,CPU立刻降了下來,在 50%~70%之間震盪。
再次調用 show prosslist,網站A 的sql 調用就很少出現在結果列表中了。但發現此主機運行了幾個 Discuz 的論壇程序, Discuz 論壇的好幾個表也存在著這個問題。於是順手一並解決,cpu佔用再次降下來了。(2007.07.09 附註:關於 discuz 論壇的具體優化過程,我後來另寫了一篇文章,詳見:千萬級記錄的 Discuz! 論壇導致 MySQL CPU 100% 的 優化筆記 http://www.xiaohui.com/dev/server/20070701-discuz-mysql-cpu-100-optimize.htm)解決 MYSQL CPU 佔用 100% 的經驗總結
增加 tmp_table_size 值。mysql 的配置文件中,tmp_table_size 的默認大小是 32M。如果一張臨時表超出該大小,MySQL產生一個 The table tbl_name is full 形式的錯誤,如果你做很多高級 GROUP BY 查詢,增加 tmp_table_size 值。 這是 mysql 官方關於此選項的解釋:
tmp_table_size
This variable determines the maximum size for a temporary table in memory. If the table becomes too large, a MYISAM table is created on disk. Try to avoid temporary tables by optimizing the queries where possible, but where this is not possible, try to ensure temporary tables are always stored in memory. Watching the processlist for queries with temporary tables that take too long to resolve can give you an early warning that tmp_table_size needs to be upped. Be aware that memory is also allocated per-thread. An example where upping this worked for more was a server where I upped this from 32MB (the default) to 64MB with immediate effect. The quicker resolution of queries resulted in less threads being active at any one time, with all-round benefits for the server, and available memory.
對 WHERE, JOIN, MAX(), MIN(), ORDER BY 等子句中的條件判斷中用到的欄位,應該根據其建立索引 INDEX。索引被用來快速找出在一個列上用一特定值的行。沒有索引,MySQL不得不首先以第一條記錄開始並然後讀完整個表直到它找出相關的行。表越大,花費時間越多。如果表對於查詢的列有一個索引,MySQL能快速到達一個位置去搜尋到數據文件的中間,沒有必要考慮所有數據。如果一個表有1000行,這比順序讀取至少快100倍。所有的MySQL索引(PRIMARY、UNIQUE和INDEX)在B樹中存儲。根據 mysql 的開發文檔:
索引 index 用於:
快速找出匹配一個WHERE子句的行
當執行聯結(JOIN)時,從其他表檢索行。
對特定的索引列找出MAX()或MIN()值
如果排序或分組在一個可用鍵的最左面前綴上進行(例如,ORDER BY key_part_1,key_part_2),排序或分組一個表。如果所有鍵值部分跟隨DESC,鍵以倒序被讀取。
在一些情況中,一個查詢能被優化來檢索值,不用咨詢數據文件。如果對某些表的所有使用的列是數字型的並且構成某些鍵的最左面前綴,為了更快,值可以從索引樹被檢索出來。假定你發出下列SELECT語句:
mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;如果一個多列索引存在於col1和col2上,適當的行可以直接被取出。如果分開的單行列索引存在於col1和col2上,優化器試圖通過決定哪個索引將找到更少的行並來找出更具限制性的索引並且使用該索引取行。
開發人員做 SQL 數據表設計的時候,一定要通盤考慮清楚。
G. 如何處理阿里雲ECS伺服器CPU利用率過高
如果你選擇的是t5類型的主機,那麼這個問題是無解的,因為這個類型本身就是限制了CPU性能基線在10%~15%,不能超過這個數字。
也有一種可能用的是共享型實例,特點是多台小雞共享一個母雞的系統資源,小雞之間存在了資源爭搶。
關於這個內容有一些解釋,長期建站和 windows 遠程桌面慎用阿里雲突發性能 t5 實例,我覺得寫的挺實在的,建議怎麼操作都有提供了
H. 阿里雲伺服器ESS是否能夠自動升降ECS的CPU,內存和帶寬
ECS支持配置升級和降級:
1、CPU、內存、硬碟、帶寬的升級通過控制台在線完成,升級後不需要重新部署環境。CPU、內存升級前需要停止,升級後重啟。硬碟和帶寬無需停機和重啟。
2、CPU、內存、帶寬降級只能在續費時進行降配操作,需要在前一個服務到期後重啟生效。
阿里雲優惠碼 LG56MI
I. 阿里雲伺服器win2008,有時候cpu佔用率100% ,查找具體原因的方法
你好!
磁碟IO的問題是一方面,另外高訪問量的Web伺服器也是不適宜在物理內存不足的情況下通過虛擬內存運行,因為內存中基本上所有數據都是熱數據,所有數據被訪問的幾率相等,一旦物理內存不足,會引發大量頁面交換操作,如果磁碟IO不行,一下就卡死了。
我用的是小鳥雲伺服器 不懂的都是問他們客服,客服還是比較專業的
希望我的回答能給你帶來幫助!有問題請追問
J. 阿里雲的ecs伺服器可以降低配置嗎
阿里雲可以升降配置,降配置的時候選擇續費降配即可。