簡單談?wù)凱HP中的Reload操作
前言
有很多前輩告誡過我們,reload 能保證整個過程的平滑性,所謂平滑性指的是在 reload 的過程中,舊的進(jìn)程在處理完當(dāng)前請求前不會提前終止。很多年來,我從來沒有質(zhì)疑過這種說法,直到有一天,當(dāng)我 reload 的時候,出現(xiàn)了 502 錯誤,讓我不得不重新思考。
如何重現(xiàn)問題呢?讓我們寫一個簡單的腳本來模擬:
<?php sleep(11); echo "foo"; ?>
此時用瀏覽器瀏覽這個網(wǎng)址,接著立刻執(zhí)行 reload 操作,就能看到 502 錯誤了。
難道 PHP 這么弱?連 reload 基本的平滑性都無法保證?答案當(dāng)然是否定的,實際上通過 process_control_timeout
參數(shù)可以實現(xiàn)我們的目標(biāo)??上н@個參數(shù)缺省是 0,也就是不生效,本文把它設(shè)置成 10s。重新執(zhí)行之前的實驗步驟,這一次正常輸出了結(jié)果。不過如果你多做幾次實驗的話,可能會發(fā)現(xiàn)當(dāng)我們 reload 的時候,sleep 立刻就結(jié)束了,這是因為 sleep 收到 reload 發(fā)出的信號后直接返回了,下面讓我們再改寫一下腳本:
<?php sleep(11); echo "foo"; sleep(11); echo "bar"; ?>
重新執(zhí)行之前的實驗步驟,你會發(fā)現(xiàn) 502 錯誤又出現(xiàn)了。這是因為 reload 雖然讓第一個 sleep 立刻結(jié)束了,但是第二個 sleep 還是有效的,而且超過了 process_control_timeout
的時間限制。如果我們把 process_control_timeout
設(shè)置為 12s,那么就又好了。
如此說來,我們只要給 process_control_timeout
設(shè)置一個合理的數(shù)值就能保證 reload 操作的平滑性,不過到底多大是合理的數(shù)值呢?太小的話可能起不到作用,太大的話會不會有副作用?讓我們帶著疑問重復(fù)上一次實驗,不過這次我們再加一個監(jiān)控:
shell> watch -n1 'ps aux | grep php[-]fpm'
此監(jiān)控的目的是為了觀察 reload 過程中 PHP-FPM 進(jìn)程數(shù)的變化情況,為了讓效果更明顯些,建議把 PHP-FPM 的啟動方式改成 static 模式,同時進(jìn)程數(shù)不要太多。
當(dāng)我們重復(fù)上一次實驗的時候,結(jié)果發(fā)現(xiàn)除了正在執(zhí)行請求的進(jìn)程,其它進(jìn)程直接就被干掉了,而新進(jìn)程又沒有立刻啟動,就這樣一直卡到最后一個舊進(jìn)程執(zhí)行完后新進(jìn)程才完成啟動過程。在此期間,如果有別的請求進(jìn)來,那么無疑它無法立刻得到響應(yīng)。
根據(jù)我們的實驗可以得出結(jié)論:缺省情況下,PHP-FPM 無法保證平滑的執(zhí)行 reload 操作,必須設(shè)置一個合理的 process_control_timeout
才行,同時需要注意的是其值不能設(shè)置的過大,否則系統(tǒng)可能出現(xiàn)更為嚴(yán)重的請求堵塞問題。
總結(jié)
以上就是關(guān)于PHP中Reload操作的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
相關(guān)文章
php access 數(shù)據(jù)連接與讀取保存編輯數(shù)據(jù)的實現(xiàn)代碼
腳本之家會給出一個php+access的留言本源碼,大家可以參考下。基本上對php access的操作就熟悉了。2010-05-05PHP入門教程之會話控制技巧(cookie與session)
這篇文章主要介紹了PHP入門教程之會話控制技巧,結(jié)合實例形式分析了cookie與session的具體使用方法與相關(guān)注意事項,需要的朋友可以參考下2016-09-09備份mysql數(shù)據(jù)庫的php代碼(一個表一個文件)
用php實現(xiàn)的備份MySQL數(shù)據(jù)庫的代碼,需要的朋友可以參考下。2010-05-05