php-cgi進程佔用cpu資源過多負載高的原因分析及解決步驟

來源:互聯網
上載者:User
php-cgi進程佔用cpu資源過多負載高的原因分析及解決步驟
    部落格分類: 

  • Linux學習筆記
PHPCGILinuxnginxRedHat

伺服器環境:redhat linux 5.5 , nginx ,  phpfastcgi

 

在此環境下,一般php-cgi運行是非常穩定的,但也遇到過php-cgi佔用太多cpu資源而導致伺服器響應過慢,我所遇到的php-cgi進程佔用cpu資源過多的原因有:

 

1. 一些php的擴充與php版本相容存在問題,實踐證明 eAccelerater與某些php版本相容存在問題,具體表現時啟動php-cgi進程後,運行10多分鐘,奇慢無比,但靜態資源訪問很快,伺服器負載也很正常(說明nginx沒有問題,而是php-cgi進程的問題),解決辦法就是從php.ini中禁止掉eAccelerater模組,再重啟php-cgi進程即可

 

2. 程式中可能存在死迴圈,導致伺服器負載超高(使用top指令查看負載高達100+), 需要藉助Linux的proc虛擬檔案系統找到具體的問題程式

 

3. php程式不合理使用session , 這個發生在開源微博記事狗程式上,具體表現是有少量php-cgi進程(不超過10個)的cpu使用率達98%以上, 伺服器負載在4-8之間,這個問題的解決,仍然需要藉助Linux的proc檔案系統找出原因。

 

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;
}

 

沒有對傳入的參數作任何初步檢查,而且設定了永不逾時,並且使用readfile一次讀取超大檔案,就可能存在以下問題:
 A. 以http方式讀取遠程附件過度耗時

 B. FTP無法串連時,如何及時反饋出錯誤?

 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檔案中

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.