衆所周知php是動態型語言,在每次處理請求時都是臨時進行代碼的編譯執行因此對於這種語言在上線時是不須要重啓的,直接採用文件覆蓋的方式進行或者採用軟鏈的方式進行替換也能夠,因爲這種特性使得其性能常常被人詬病,因此就有了php-fpm這種進程管理工具來配合其使用,使得現在php-fpm成爲了php的標配(apache就不是利用這種的),可是php-fpm是用c編寫的,c是靜態型語言,因此在修改php-fpm的配置時仍是須要重啓的(不過這種狀況一幫不多見),那麼在須要重啓時php-fpm又是如何運做的呢? 下面來說講。php
在平滑重啓時須要考慮的問題通常有兩方面:一方面,未結束的請求如何處理,另外一方面,進程處理時間過長如何處理。對於這兩個方面,php-fpm都給出了本身的解決方法,這兩方面是相互進行的,不是獨立的。apache
注意:給php-fpm發送重啓信號kill -USR2 pid 這個pid既能夠是master進程的pid,也能夠是worker進程的pid,若是是master進程的pid就會吧全部worker進程重啓,若是是worker進程的pid就是隻重啓當個worker進程。bash
未結束的請求如何處理:函數
發送重啓信號是會通知master,master獲取event而後給worker進程發送退出的信號SIGQUIT,worker進程接收信號後交給對應的信號處理函數處理,信號函數就是將in_shutdown變量置爲1,這樣worker進程 在調用fcgi_accept_request進程下一個進程處理時就不接收直接退出了,(注意這裏也會有處理時間過長問題),若是進程尚未執行結束也會退出,這樣就會出現代碼邏輯執行一半的狀況,因此要特別注意。從這裏能夠看出來php-fpm的重啓邏輯簡單粗暴,(在規定時間內處理完請求,完成不了就無論了),因爲php-fpm一個worker進程每次只能處理一個請求,因此不須要計數器之類的,這樣就更簡單了。php-fpm
處理時間過長如何處理:工具
在給php-fpm進程發送信號時,php-fpm進程就會重啓操做流程,在整個重啓操做流程當中爲了保證順利的重啓增長了超時機制,超過了設置的時間就會強制重啓,中斷正在進行中的進程。這個配置是在php-fpm.ini文件中設置的,process_control_timeout=10 這個字段就是用來設置的,表示最多10秒。性能
實例: 測試
代碼測試,在設置10秒超時狀況下,代碼邏輯須要11秒的狀況下,重啓會形成代碼執行部分而後退出的狀況。ui
public function actionTest(){
$model = new bad();
$model->save(array('id'=>75329370));
//須要特別注意不能使用sleep方法進行時間的等待,
//由於是調用系統的sleep方法,在重啓時會使其失效
$model->db()->query('select sleep(11) from orders where id=75329370');
$model2 = new lock();
$model2->save(array('id'=>10251,'info'=>1212));
return;
}複製代碼