轉的網上的,不過對PHP-CGI菜鳥的人,仍是有點幫助的。php
1. 一些php的擴展與php版本兼容存在問題,實踐證實 eAccelerater與某些php版本兼容存在問題,具體表現時啓動php-cgi進程後,運行10多分鐘,奇慢無比,但靜態資源訪問很快,服務器負載也很正常(說明nginx沒有問題,而是php-cgi進程的問題),解決辦法就是從php.ini中禁止掉eAccelerater模塊,再重啓php-cgi進程便可nginx
2. 程序中可能存在死循環,致使服務器負載超高(使用top指令查看負載高達100+), 須要藉助Linux的proc虛擬文件系統找到具體的問題程序shell
3. php程序不合理使用session , 這個發生在開源微博記事狗程序上,具體表現是有少許php-cgi進程(不超過10個)的cpu使用率達98%以上, 服務器負載在4-8之間,這個問題的解決,仍然須要藉助Linux的proc文件系統找出緣由。bash
4. 程序中存在過分耗時且不可能完成的操做(仍是程序的問題),例如discuz x 1.5的附件下載功能: source/module/forum/forum_attachement.php中的定義服務器
function getremotefile($file) {
global $_G;
@set_time_limit(0);
if(!@readfile($_G['setting']['ftp']['attachurl'].'forum/'.$file)) {
$ftp = ftpcmd('object');
$tmpfile = @tempnam($_G['setting']['attachdir'], '');
if($ftp->ftp_get($tmpfile, 'forum/'.$file, FTP_BINARY)) {
@readfile($tmpfile);
@unlink($tmpfile);
} else {
@unlink($tmpfile);
return FALSE;
}
}
return TRUE;
}cookie
沒有對傳入的參數做任何初步檢查,並且設置了永不超時,而且使用readfile一次讀取超大文件,就可能存在如下問題:
A. 以http方式讀取遠程附件過分耗時session
B. FTP沒法鏈接時,如何及時反饋出錯誤?ide
C. readfile是一次性讀取文件加載到內存中並輸出,當文件過大時,內存消耗驚人優化
根據實驗發現採用readfile一次性讀取,內存消耗會明顯增長,可是CPU的利用率會降低較多。若是採用分段讀取的方式,內存消耗會稍微降低,而CPU佔用卻會明顯上升。網站
對discuz x 1.5的這個bug較好解決方法就是後臺從新正確設置遠程附件參數。
如下是我逐步整理的故障排除步驟:
1. 獲得佔用cpu資源過多的php-cgi進程的pid(進程id), 使用top命令便可,以下圖:
通過上圖,咱們發現,有兩個php-cgi進程的cpu資源佔用率太高,pid分別是10059,11570,這通常都是程序優化不夠形成,如何定位問題的php程序位置?
2. 找出進程所使用的文件
/proc/文件系統保存在內存中,主要保存系統的狀態,關鍵配置等等,而/proc/目錄下有不少數字目錄,就是進程的相關信息,以下圖,咱們看看進程10059正在使用哪些文件?
顯然,使用了/home/tmp/sess_*文件,這明顯是PHP的session文件, 咱們查看這個session文件的內容爲:view_time|123333312412
到這裏,咱們已經能夠懷疑是因爲php程序寫入一個叫view_time的session項而引發, 那麼剩餘的事件就是檢查包含view_time的全部php文件,而後修改之(好比改用COOKIE),這實話, 這個view_time並不是敏感數據,僅僅記錄用戶最後訪問時間,實在不必使用代價巨大的session, 而應該使用cookie。
3. 找出有問題的程序,修改之
使用vi編輯如下shell程序(假設網站程序位於/www目錄下)
#!/bin/bash
find /www/ -name "*.php" > list.txt
f=`cat ./list.txt`
for n in $f
do
r=`egrep 'view_time' $n`
if [ ! "$r" = "" ] ; then
echo $n
fi
done
運行這個shell程序,將輸出包含有view_time的文件, 對記事狗微博系統,產生的問題位於modules/topic.mod.class文件中