天天看點

一次網站性能排查實錄

接到一個求助電話,說是有個阿裡雲上的伺服器,有性能瓶頸,但又沒有什麼具體的資料,隻是說偶爾用戶端有少數連接配接不上,或者連接配接會突然中斷。我的天,最怕這種狀況了,還得自己去找問題表現是什麼,再去找什麼原因所緻。----懶人可直接點此處,不必辛苦看文字

因為是線上的環境,得分兩步進行。先檢查,看系統或者應用存在什麼明顯的印迹,分析原因和處理方法;協商什麼時候可以處理,處理風險是什麼。

怕影響使用者體驗,白天還不讓搞。月黑風高,家裡有沒暖氣啊(用一塊閑置顯示卡挖礦取暖),沒辦法,隻好熬夜苦戰一番。

通過了解,該雲主機帶寬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,你寫起來省事,可是後邊維護就不那麼省事。

一次網站性能排查實錄

沒辦法,我認了。再進具體包含檔案的目錄,随機打開一個,截取一段如下:

一次網站性能排查實錄

包含裡邊嵌套包含,那好,我們就看看它這個包含裡邊寫的啥:

[[email protected] 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端口處于監聽狀态。

[[email protected] ~]# netstat -anp|grep 9000|wc -l|grep -v grep

打開其它站點配置檔案,全是這個搞法。得統一做規範,友善自己也是友善他人嘛!不過亂歸亂,還是能正常運作,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)也需要設定大一些。

把這些問題,記錄好彙總以後,電話跟其他人溝通,得到答複是等相關人等線上的時候進行修正,萬一業務上有問題,可以一起協助處理,但得等兩天以後。欲知詳細的操作過程,調整後的效果,請猛戳此處即可。

本文轉自sery51CTO部落格,原文連結:http://blog.51cto.com/sery/2053947 ,如需轉載請自行聯系原作者