本文目錄一覽:
- 1、如何寫php守護進程
- 2、如何用supervisor守護php-fpm主進程以實現php-fpm的自動重啟
- 3、linux 怎麼證明該進程是php的守護進程
- 4、php 後台怎麼開一個進程監聽Redis的隊列消息呢?用while
- 5、如何將我的php腳本以守護進程的方式一直運行
如何寫php守護進程
關於這個問題,首先,已經很有幾個熱心人士回答了,我再重複一遍,也沒有什麼意義一,而且他們回答的都很對,你如果不明白,問他們也可以問我也可以,我這些都是在後盾上學的,有空可以去看一下,就算不喜歡也沒關係啊,何樂而不為呢?
如何用supervisor守護php-fpm主進程以實現php-fpm的自動重啟
1. 安裝supervisor
supervisor本身是python實現的,而且是調研階段,故先創建一個新的virtualenv環境,然後用pip安裝好supervisor包。
至此,基本的調研環境搭建完畢。當然,php-fpm和PHP環境以及前端的Nginx是早就ready的。
2. 分析php-fpm.sh腳本
通常編譯安裝PHP後,php-fpm這個2進制的C程序也會被編譯並安裝好,典型路徑在php_install_path/sbin/目錄下。該
目錄下還有個名為php-fpm.sh的腳本用於控制php-fpm進程的start/stop/restart/reload等動作。
./sbin/php-fpm.sh腳本中,”start”操作啟動了php-fpm主進程,其餘的操作都是通過向php-fpm master進程發signal實現的。
code class=”hljs bash”## code segment in php-fpm.sh
case “$1” in
start)
echo -n “Starting php-fpm “
## 下面這行是關鍵命令
$php_fpm_BIN –daemonize $php_opts
if [ “$?” != 0 ] ; then
echo ” failed”
exit 1
fi
wait_for_pid created $php_fpm_PID
if [ -n “$try” ] ; then
echo ” failed”
exit 1
else
echo ” done”
fi
;;/code
從上面是終端輸入”./sbin/php-fpm.sh
start”時,實際執行的代碼,可以看到,php-fpm進程的啟動參數是–daemonize
$php_opts,而$php_opts的值為”–fpm-config $php_fpm_CONF –pid $php_fpm_PID”。
注意: php-fpm.sh啟動php-fpm master進程時,傳入了daemonize參數,表明php-fpm master process以守護(daemon)方式啟動,而根據supervisor文檔的說明,當用supervisor監護進程時,被監護進程不能是守護進程,這是由於守護進程通常會在fork完子進程後就讓父進程”結束生命”,也即由supervisor創建的父進程退出,此時,supervisor無法再監護已退出進程創建出來的子進程。關於daemon process的行為,可以參考Linux Daemon Writing HOWTO一文來理解。
根據上面的分析,我們知道,只要supervisor啟動php-fpm進程時,不傳入daemonize參數即可。
3. 實現php-fpm主進程守護功能的supervisor配置文件
上面的分析已經告訴我們應該怎麼解決問題了,下面直接上驗證可用的配置文件。文件位於php-fpm.conf同級目錄下(典型路徑為php_install_path/etc/)。
code class=”hljs bash”code class=”hljs vhdl”
[inet_http_server] ; inet (TCP) server disabled by default
port=127.0.0.1:9015 ; (ip_address:port specifier, *:port for all iface)
[supervisord]
logfile=./var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=2 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=./var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
identifier=sup.php-fpm ; (supervisord identifier, default is ‘supervisor’)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl= ; use an http:// url to specify an inet socket
[program:php-fpm]
command=bash -c “sleep 1 /home/slvher/tools/php/5.6.11/sbin/php-fpm –fpm-config /home/slvher/tools/php/5.6.11/etc/php-fpm.conf –pid /home/slvher/tools/php/5.6.11/var/run/php-fpm.pid” ; the program (relative uses PATH, can take args)
process_name=%(program_name)s ; process_name expr (default %(program_name)s)
autostart=true ; start at supervisord start (default: true)
autorestart=true ; whether/when to restart (default: unexpected)
startretries=5 ; max # of serial start failures (default 3)
exitcodes=0,2,70 ; ‘expected’ exit codes for process (default 0,2)
stopsignal=QUIT ; signal used to kill process (default TERM)
stopwaitsecs=2 ; max num secs to wait b4 SIGKILL (default 10)
/code/code
配置文件結構通過查看supervisor文檔很容易就能掌握,有兩個配置項需要特別注意:
1) command
它指定了supervisor要監控的進程的啟動命令,可以看到,這裡我們沒有給php-fpm傳入daemonize參數,其餘參數只是展開了php-fpm.sh中的shell變量而已。
大家已經注意到,command也不是直接調起php-fpm,而是通過bash -c執行了兩個命令,而第一個命令是sleep 1。這是由於php-fpm在stop後,其佔用的端口通常不能立即釋放,此時,supervisor以極快的速度試圖重新拉起進程時,可能會由於報如下錯誤而導致幾次retry均失敗:
code class=”hljs bash”code class=”hljs vhdl”code class=”hljs vbscript”## var/log/php-fpm.error.log
[18-Jul-2015 21:35:28] ERROR: unable to bind listening socket for address ‘127.0.0.1:9002’: Address already in use (98)
[18-Jul-2015 21:35:28] ERROR: FPM initialization failed/code/code/code
而supervisor目前還不支持delay restart功能,因此,這裡只能通過先sleep再啟動的略顯tricky的方法來解決問題,結果表明,療效不錯且無副作用。-_-
2) autorestart
其文檔描述如下:
code class=”hljs bash”code class=”hljs vhdl”code class=”hljs vbscript”code class=”hljs livecodeserver”May be one of false, unexpected, or true. If false, the process will never be autorestarted. If unexpected, the process will be restart when the program exits with an exit code that is not one of the exit codes associated with this process’ configuration (see exitcodes). If true, the process will be unconditionally restarted when it exits, without regard to its exit code./code/code/code/code
其默認值是unexpected,表示若被監護進程的exit code異常時,supervisor才會重新拉起進程。這裡設置為true,表明任何時候進程退出均會被再次拉起。
這樣配置好後,在本文第1步搭建好的virtualenv環境中,運行如下命令即可完成supervisor對php-fpm master進程的監護:
code class=”hljs bash”code class=”hljs vhdl”code class=”hljs vbscript”code class=”hljs livecodeserver”code class=”hljs avrasm”shell supervisord -c etc/sup.php-fpm.conf/code/code/code/code/code
然後,通過ps x | fgrep fpm可以看到,php-fpm主進程已經被拉起了。
然後,kill掉php-fpm主進程,再次ps x | fgrep fpm可以看到,一個新的php-fpm主進程會被supervisor創建出來。
至此,用supervisor守護php-fpm主進程以實現php-fpm的自動重啟的需求已經解決了。
linux 怎麼證明該進程是php的守護進程
進程A監控進程B,發現進程B異常退出的時候就自動重啟進程B。 進程A就稱為進程B的守護進程。
php 後台怎麼開一個進程監聽Redis的隊列消息呢?用while
redis的subscribe用pconnect鏈接,執行這個腳本的進程會自動監聽所訂閱的頻道發送的消息
ini_set(‘default_socket_timeout’, -1);
$redis = new \Redis();
$redis-pconnect(‘127.0.0.1’, 6379);
//訂閱
$redis-subscribe([‘msg’], ‘callfun’);
function callfun($redis, $channel, $msg)
{
var_dump([
‘redis’ = $redis,
‘channel’ = $channel,
‘msg’ = $msg
]);
}
如何將我的php腳本以守護進程的方式一直運行
用一個簡單可靠的Shell腳本來守護一個可能會突發退出的PHP服務
/etc/rc.local 里加入開機啟動命令:
原創文章,作者:X3BON,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/128954.html