Apache 無響應/偶爾停止
我在 Debian GNU/Linux 8 (jessie) 上執行帶有 PHP 7.0 和 MySQL 5.5 的 Apache http server 2.4。有時,Apache 會在幾秒鐘內完全無響應 - 大約 30 秒或更長時間。在這個時候,請求似乎在排隊——當 Apache 終於重新開始正常工作時,很多堆積起來的請求必須一次處理,這當然也不是很好。
Apache 無響應的原因尚不清楚,因為:
- CPU 負載完全下降;Apache、MySQL 或其他任何東西都不會顯著使用 CPU
- Apache error_log 中沒有錯誤
- MySQL 中沒有阻塞查詢 - 當我輸入“SHOW PROCESSLIST”時沒有顯示
- 每秒一次,“內部虛擬連接”在 access_log 中可見
- 伺服器上的總負載不能太高才能發生這種情況;即使負載低於平均水平且沒有多少使用者登錄我們的系統,也可能發生這種情況
- 甚至包含 only 的 PHP 腳本
echo "Hello World!";
也不會執行- 在 PHP 中,沒有拋出 MySQL 錯誤,我可以輕鬆地從 MySQL 控制台執行 MySQL 語句
- RAM 似乎沒問題 - 交換分區沒有被大量使用。這是
top
在攤位上說的:KiB Mem: 6129344 total, 5975748 used, 153596 free, 24 buffers KiB Swap: 1952764 total, 199428 used, 1753336 free. 4397256 cached Mem
我嘗試使用 strace 分析問題 - 準確地說,當我注意到伺服器變得無響應時,我在 shell 中輸入:
ps auxw | grep apache | awk '{print" -p " $2}' | xargs sudo strace
我觀察到的是,在此期間,在 strace 輸出中經常可以看到類似以下的行,但有時在不存在問題的情況下它們不會:
[pid 13521] fcntl(57, F_SETLK, {type=F_RDLCK, whence=SEEK_SET, start=1073741824, len=1}) = -1 EAGAIN (Resource temporarily unavailable)
通常,當沒有問題時,我可以看到如下行:
[pid 3414] fcntl(55, F_SETLK, {type=F_RDLCK, whence=SEEK_SET, start=1073741824, len=1}) = 0
有誰知道這意味著什麼?在我看來,存在某種鎖定衝突……
為了完整起見,這是我的 Apache 配置:
LogFormat "%h PID %P %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" %V" common ServerTokens ProductOnly ServerSignature Off TraceEnable off <IfModule mod_ssl.c> SSLHonorCipherOrder On SSLProtocol ALL -SSLv2 -SSLv3 SSLCipherSuite EECDH+AES:AES256-SHA:AES128-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH:!EXP:!SRP:!DSS:!LOW; SSLVerifyClient none SSLVerifyDepth 1 SSLInsecureRenegotiation Off </IfModule> ScriptAlias /cgi-bin52/ /usr/share/phpcgi/php52/ ScriptAlias /cgi-bin53/ /usr/share/phpcgi/php53/ ScriptAlias /cgi-bin54/ /usr/share/phpcgi/php54/ ScriptAlias /cgi-bin55/ /usr/share/phpcgi/php55/ ScriptAlias /cgi-bin56/ /usr/share/phpcgi/php56/ ScriptAlias /cgi-bin70/ /usr/share/phpcgi/php70/ Mutex flock LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so LoadModule status_module /usr/lib/apache2/modules/mod_status.so AcceptFilter http none AcceptFilter https none ExtendedStatus on TimeOut 60 KeepAlive Off MaxKeepAliveRequests 50 KeepAliveTimeout 2 Options Indexes MultiViews FollowSymLinks MaxRequestWorkers 256 MaxRequestsPerChild 300
你看,已經有一個與鎖定行為相關的條目:
Mutex flock
……正如他所說,出於穩定性原因,它是由我的 Webhoster 預先配置的。此外,在https://httpd.apache.org/docs/2.4/mod/core.html#mutex,這似乎是少數幾個沒有任何問題的選項之一。我
AcceptFilter
在嘗試找到解決方案時添加了條目,但沒有成功。誰能解釋我使用 strace 記錄的行是什麼
fcntl ...
意思,或者建議另一種分析問題的方法?
您可以查看
strace
阻塞的文件編號。當您執行操作時,ls -l /proc/$pid/fd
您將看到該程序的所有打開文件。帶有文件號的符號連結將指向相關文件。我見過這樣的問題,通常是會話文件有這個問題。如果它是會話文件,請讓您的開發人員了解
session_write_close()
PHP 中的功能以及省略session_write_close()
對您在負載下的性能的影響。
fcntl 是試圖設置文件描述符的核心。您沒有關注的一件事是磁碟輸入/輸出等待時間,因此執行 iostat 或 mpstat 以查看在遇到問題時是否存在任何磁碟性能問題。