2015-04-21 138 views
1

我有一個PHP腳本,需要很長時間,並使許多DB連接。PHP/FastCGI錯誤500

約5分鐘後,服務器將我錯誤500和error_log中顯示以下內容:

(104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server 
(104)Connection reset by peer: mod_fcgid: ap_pass_brigade failed in handle_request_ipc function 

我用Google搜索,發現這個明顯的答案是改變內部無論是「PHP_FCGI_MAX_REQUESTS」變量「 fcgi-bin/php5.fcgi「文件或者Apache配置文件中的」FcgidMaxRequestsPerProcess「變量,但是我不能執行其中的任何一個,因爲服務器承載多個網站,所有網站都運行FastCGI。

我試圖捕獲錯誤500,並與下面的PHP代碼重定向頁面:

register_shutdown_function('rerun'); 

$rerun = isset($_GET['rerun']) ? true : false; 
main($rerun); 

function main ($rerun=false) { 
    // Lots and lots of stuff 
} 
function rerun() { 
    if (error_get_last() != NULL) { 
     header('Location: http://www.example.com/myscript.php?rerun'); 
    } 
} 

但它也不管用,我還是結了一個錯誤500

不任何人有任何想法如何解決這個問題? 要麼通過在本地聲明FastCGI變量(即僅用於本網站),或者最好是正確捕獲錯誤500並在所有崩潰之前觸發「重新運行」功能。

回答

0

我想這是因爲你的腳本沒有發送任何數據到Apache。而且由於等待來自fast-cgi的apache的響應超時,你得到了這個錯誤。我在nginx + php-fpm上有類似的問題。我已經與此變通辦法解決它:

function explicitBufferFlush() 
{ 
    echo str_repeat('*', 1024 * 64); 
    flush(); 
    ob_flush(); 
} 

它所做的只是它發送*輸出,同時你的腳本運行的Apache收到的數據和不落的連接。你可以在一些重循環或其他任何事情的每一次迭代中調用它。或者你可以嘗試設置FcgidIOTimeout指令在你的.htaccess中的某些高價值

+0

我已經在我的'main'函數中向apache發送了大量的數據,這似乎不成問題。我無法在我的.htaccess文件中設置'FcgidIOTimeout'(或任何'FcgidANYTHING'),我得到一個直接的錯誤500,並且在日誌中:'/my/path/to/website/.htaccess: FcgidIOTimeout不允許在這裏。 – roberto06

+0

@ roberto06當腳本處理數據時,你是否收到任何輸出到瀏覽器? – Tony

+0

不知道,原因不明,'flush()'和'ob_flush()'在我的任何瀏覽器上似乎都不起作用(但它們在stdout中工作)。 – roberto06

0

對不起,剛剛遇到這個問題後很久才問到,你可能已經解決了這個問題,但是因爲我遇到了這個之前,我想我會把它扔給那些正在搜索的人......

通常,FastCGI進程的超時時間爲5分鐘。很可能你會得到錯誤,因爲FastCGI在5分鐘後中止,從而阻止它向Apache發送任何輸出。嘗試將超時時間增加到10分鐘,或者大幅減少正在進行的處理,以證明情況正是如此。

FastCGI進程超時與PHP超時不同,它是對進程啓動以來的時間進行簡單計算,而不是進程中的時間,這是PHP超時所基於的時間。 (換句話說,花在等待數據庫響應上的時間不計入PHP超時時間,但它確實會計入FastCGI超時時間,因此,即使PHP的超時設置較短,您仍然可以首先啓用FastCGI超時。