一次網站性能排查實錄
因為是線上的環境,得分兩步進行。先檢查,看系統或者應用存在什麽明顯的印跡,分析原因和處理方法;協商什麽時候可以處理,處理風險是什麽。
怕影響用戶體驗,白天還不讓搞。月黑風高,家裏有沒暖氣啊(用一塊閑置顯卡挖礦取暖),沒辦法,只好熬夜苦戰一番。
通過了解,該雲主機帶寬12M,其他方面的配置,我自己登錄看就好。
既然收到帶寬,就先看它了,看了好一陣,也不到10M嘛。
其他資源配置為:
(1)cpu 8core
(2)內存 16G
(3)硬盤 50G系統加120G外掛空間。
其中系統負載一直穩定不高,IO也還過得去,系統日誌也無明顯的報錯信息。查看網絡狀態,TIME_WAIT相對於ESTABLESHED來說,高了不少(因為文章為事後所寫,無法再重現了)。根據經驗,大致可以判斷引起TIME_OUT高的原因主要有兩種:一種是系統參數(sysctl.conf)設置,另一種就是應用服務配置。前一種比較好辦,乘訪問量少的時候,偷偷的修改/etc/sysctl.conf(修改前一定要記得備份喲),然後重載 sysctl -p,再執行netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}',發現TIME_OUT的數量並沒有減少多少。由此可知,最大的可能就在系統上邊的應用。
當然,作為系統管理員,不可能啥都去問人家,你上邊安裝了什麽,都在啥目錄啊,程序之間都什麽關聯?只要有系統登錄權限,哪能難住咱們呢!敲ps auxww |more 加一點點耐心,能查個八九不離十。不就是一個nginx + php + mysql 嘛,挨個檢查,應該能查到問題所在。這一回車,好多php進程呢,屏幕翻滾了好幾屏。心想,沒那麽多連接數,跑那麽多進程幹啥呢?做過過濾,數一下php進程數,好家夥301個。
我有個習慣,喜歡從後邊往前邊查。於是就從數據庫開查,show processlist,沒線程連接上來,奇怪了啊。還以為自己煙花,又執行了好幾遍,還是這樣。檢查mysql錯誤日誌,數據目錄,毫無所獲,難道不是用這個mysql?吃個橘子壓壓驚,查看網絡狀態,看它連接到哪裏去了。
居然沒用本機的mysql(不知道裝這個幹啥),趕緊電話問,說是購買了阿裏雲的mysql服務,好吧,看來這個就不用查了。
接下來,該看看nginx了。這一查,還真找到幾個不順眼的地方。按照我的習慣,如果系統上要運行多個web站點,一般都會用明確包含的方式對配置文件進行書寫,這樣做的好處是,看到主配置文件,就知道有多少站點;而且做維護的時候,如果某些站點要臨時變更或者變更後整個web服務啟動不了,就可以通過註釋掉相關的那行包含(include)語句。最不喜歡誰用什麽 include *.conf,你寫起來省事,可是後邊維護就不那麽省事。
沒辦法,我認了。再進具體包含文件的目錄,隨機打開一個,截取一段如下:
包含裏邊嵌套包含,那好,我們就看看它這個包含裏邊寫的啥:
[root@iZm5e64s4c3fznr1kxv1qaZ conf]# more enable-php.conf location ~ [^/]\.php(/|$) { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf |
又有一個嵌套,狂暈啊!繼續看這個fastcgi.conf,就是一個fastsgi_params文件的副本。
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; |
各位看官,再往下看這個文件,又來了個fastcgi_pass 127.0.0.1 ,是要用什麽方式關聯php呢?前邊那個include指定的"fastcgi_pass unix:/tmp/php-cgi.sock;" 後邊又跟這麽一個是什麽用意?
看到沒有,這個fastcgi_pass 127.0.0.1 根本沒起作用啊,可能是從網上找的,胡亂粘貼一通。另外,也從php那邊印證一下,確認服務是否有tcp 9000端口處於監聽狀態。
[root@iZm5e64s4c3fznr1kxv1qaZ ~]# netstat -anp|grep 9000|wc -l|grep -v grep 0 |
打開其它站點配置文件,全是這個搞法。得統一做規範,方便自己也是方便他人嘛!不過亂歸亂,還是能正常運行,nginx本身也不會對性能產生太大的影響。由這裏可以推斷,php估計也是胡亂從別的地方復制過來的配置,其內容如下:
[global] pid = /usr/local/php/var/run/php-fpm.pid error_log = /usr/local/php/var/log/php-fpm.log log_level = notice [www] listen = /tmp/php-cgi.sock listen.backlog = -1 listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www listen.mode = 0666 user = www group = www pm = dynamic pm.max_children = 300 pm.start_servers = 80 pm.min_spare_servers = 80 pm.max_spare_servers = 300 access.log = /mnt/log/phplog/$pool.access.log access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" pm.max_requests = 1024 request_terminate_timeout = 0 request_slowlog_timeout = 120 slowlog = /var/log/slow.log |
這幾個選項值,直接與性能相關。查看php進程數,一直就是設定的數量300(主進程不算)。最大300,而且一直維持不變,新來的請求無法獲得新的進程,於是就只好殺掉已經運行的(有可能用戶的連接還在),類似於自殺,可以從php的日誌裏可以看到大量的進程自殺消息。
一般情況下,應該把最大子進程數(pm.max_children = 300)設置得大一些,最大請求數(pm.max_requests)也需要設置大一些。
把這些問題,記錄好匯總以後,電話跟其他人溝通,得到答復是等相關人等在線的時候進行修正,萬一業務上有問題,可以一起協助處理,但得等兩天以後。欲知詳細的操作過程,調整後的效果,請猛戳此處即可。
一次網站性能排查實錄