如果下載中斷,PHP + Fcgid 將掛起

如果下載中斷,PHP + Fcgid 將掛起

筆記:管理員們,請投票支援遷移到 ServerFault。

我正在使用 LAMP 設置,PHP 通過mod_fcgid.對於大多數請求,這效果很好,但我注意到,當我下載文件但在下載完成之前中斷下載時,為文件提供服務的 php-cgi 進程會阻止嘗試寫入更多數據,直到達到為止IPCCommTimeout。一旦達到逾時,進程就會中斷,並且流程會再次開始為其他請求提供服務。

fcgid 是否有一些可用的設置,如果沒有任何內容捕獲輸出,我可以將其設置為中止?我可以用 PHP 做些什麼來處理它嗎?

如果下載不中斷,則不會出現此問題;事實上,我只是注意到它,因為我試圖使用 gddflvplayer 串流 FLV 文件,它似乎發送一個簡短的請求來獲取前幾幀,然後發送另一個請求來播放它,這會導致同樣的問題。

僅供參考,這是掛起的 cgi 進程的 strace;它會像這樣坐著,直到最終被中斷,大概是在IPCCommTimeout達到 時被流程管理器中斷。我的猜測是它在嘗試輸出呼叫結果時掛起readfile(),但 Apache 不再偵聽(因為請求已被使用者取消)。

root@some-machine:~# strace -p 24837
Process 24837 attached - interrupt to quit
write(3, "\5|A\313%\35\337\376\275\237\230\266\242\371\37YjzD<\322\215\357\336:M\362P\335\242\214\341"..., 17432

日誌顯示該請求由於逾時最終被收割

mod_fcgid: read data timeout in 240 seconds

下載程式碼或多或少只是用於readfile提供文件,還涉及一些標頭(注意:在此程式碼中,Header或多或少只是一個包裝器,header()以避免測試中出現問題)。

$filepath    = '/some/path/foo.flv';
$filename    = 'foo.flv';
$disposition = 'inline';

$h = Header::get();
$h->send('Pragma: public');
$h->send('Content-Transfer-Encoding: binary');
$h->send('Content-type: ' . FileSystem::get()->getMimeType($filepath));
$h->send('Content-Length: ' . FileSystem::get()->getFileSize($filepath));
$h->send('Content-Disposition: ' . $disposition . '; filename="' . $filename . '"');
$h->send('Content-transfer-encoding: 8bit');
$h->send('Expires: 0');
$h->send('Pragma: cache');
$h->send('Cache-Control: private');

flush();
readfile($filepath);

相關內容