首頁  >  文章  >  後端開發  >  php中fastcgi_finish_request的介紹及其實作非阻塞的程式碼

php中fastcgi_finish_request的介紹及其實作非阻塞的程式碼

不言
不言原創
2018-08-25 17:21:123452瀏覽

這篇文章帶給大家的內容是關於php中fastcgi_finish_request的介紹及其實現非阻塞的程式碼,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

前言

在實際專案中經常會有這樣的需求,對於前端發過來的請求,需要在後端進行長時間的處理,但為了讓使用者有更好的體驗,為了讓PHP在後端處理長時間任務時不阻塞,快速回應頁面請求,因此在這裡對fastcgi_finish_request的應用進行總結歸納。當然php實作非阻塞的方式有很多種,像是非同步腳本、swoole,但個人認為fastcgi_finish_request最為簡單方便。

基本應用程式

fastcgi_finish_request介紹

(PHP 5 >= 5.3.3, PHP 7)

fastcgi_finish_request — 沖刷(flush)所有回應的資料給客戶端

boolean fastcgi_finish_request ( void )

此函數沖刷(flush)所有回應的資料給客戶端並結束請求。這使得客戶端結束連線後,需要大量時間運行的任務能夠繼續運作。

傳回值

成功時回傳TRUE, 或是失敗時回傳FALSE

注意問題

  • PHP 與Web 伺服器使用了PHP-FPM(FastCGI進程管理器),那透過fastcgi_finish_request() 函數能馬上結束會話,而PHP 執行緒可以繼續在後台運行。也就是說只針對php-fpm的進程管理方式才能使用該函數

  • 只要程式碼運行到這個位置,就已經斷開請求返回參數給客戶端了。接下來的程式碼都跟客戶端沒有關係了。也就是說輸出在頁面的內容必須放在fastcgi_finish_request函數之前

  • fastcgi_finish_request()結束客戶端連線之後,運行時間依然會受max_execution_time逾時時間的影響,也就是說如果預計到程式碼在後端執行時間比較久,還是要設定set_time_limit(0)

  • #在高並發下執行時間過久也會導致fastcgi進程不夠用,無法及時釋放,就會爆502錯誤了。

應用程式

echo "program start...";

file_put_contents('/tmp/garylog.log','start-time:'.date('Y-m-d H:i:s')."\n", FILE_APPEND);

fastcgi_finish_request();sleep(1);

// set_time_limit(0);
// sleep(150);

$num = 25;
$num += 1;
sleep(5);
echo 'debug...';
file_put_contents('/tmp/garylog.log', 'start-proceed:'.$num.',时间'.date('Y-m-d H:i:s')."\n", FILE_APPEND);

sleep(10);

file_put_contents('/tmp/garylog.log', 'end-time:'.date('Y-m-d H:i:s')."\n", FILE_APPEND);

執行測試

php中fastcgi_finish_request的介紹及其實作非阻塞的程式碼

php中fastcgi_finish_request的介紹及其實作非阻塞的程式碼

##相容非php-fpm

從程式碼的可移植性講的話, 可以在程式碼中附上如下程式碼:

    if (!function_exists("fastcgi_finish_request")) {
          function fastcgi_finish_request()  {
          }
    }
不會造成程式碼部署在非fpm環境下造成問題.

保證進程單一運行

#對於上面說到的問題:在高並發下執行時間過久也會導致fastcgi進程不夠用,無法及時釋放。同時我們的需求只是為了起到觸發的作用,並不需要每次運行,那麼可以考慮使用下面的方法,避免重複佔用進程。

 $processId = realpath(__FILE__) . '-' . get_class($this);
$filename = md5($processId);
$file = '/tmp/'.$filename;
if(!file_exists($filename)){
    file_put_contents($file, getmypid());
}else{
    return true; 
}


## do somthing 需要长时间处理的代码

//处理完成后删除进程id记录文件
unlink($file);
相關推薦:

php中神奇的fastcgi_finish_request

##PHP利用fastcgi_finish_request()函數實現非同步操作,提高響應速度

#

以上是php中fastcgi_finish_request的介紹及其實作非阻塞的程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn