在 Centos 上守护 php 脚本
Daemonizing php script on Centos
运行 尝试在 Centos Linux 环境中守护 php 脚本时遇到一些问题。可惜Centos只有有限的daemon功能,没有start-stop-daemon...
我正在尝试创建一个持续运行 php 脚本的服务,直到捕获到信号。我也想要一个 php 脚本来启动服务。
- foolauncher.php 通过系统启动服务('service foo start')
- /etc/init.d/foo 开始 foo.php
- foo.php 生成 child 进程进行守护进程并 parent 退出
然而,当我启动 foolauncher.php 时,它显示 init.d 脚本启动我的 foo.php 服务,不释放终端,而是输出我的系统调用。当我发送 SIGINT 退出 parent 时,foo 服务也会停止 运行。
我知道问题出在foo.php:
$output = system('service foo status');
如果我省略系统调用的那一行,发送 SIGINT 退出 parent 将不会影响 foo 服务。
我知道 fclose(STDERR)、fclose(STDOUT) 和 fclose(STDIN),但我不确定我实际关闭这些输出的位置,因为它似乎会导致与发送类似的问题SIGINT 到 parent; foo.php 仍然同样死于系统调用。
好像是因为我正在向 STDOUT 输出一些东西,所以 parent 无法完全释放 child...我不打算使用其他的 deamonizing 方法(即. System Daemon, nohup), or using a cron job to execute (even he hard the daemonizing php is not a good idea), but a solution to how to solve this problem.
如有任何建议、建议或解决方案,我们将不胜感激!谢谢!
文件如下:
foolauncher.php:
<?php
system('service foo start');
foo.php:
<?php
declare(ticks = 1);
$pid = pcntl_fork();
if ($pid < 0)
{
system("echo 'failed to fork' >> /foo/foo.log");
exit;
}
else if ($pid)
{
system("echo 'parent exiting' >> /foo/foo.log");
exit;
}
$sid = posix_setsid();
if ($sid < 0)
{
exit;
}
pcntl_signal(SIGTERM, "signalHandler");
pcntl_signal(SIGINT, "signalHandler");
$daemonPid = posix_getpid();
system("echo 'Process started on $daemonPid!\n' >> /foo/foo.log");
system("echo $daemonPid > /var/run/foo.pid");
while(true)
{
// If I dont have this line, everything daemonizes nicely
$output = system("service foo status");
system("echo 'In infinite loop still! $output\n' >> /foo/foo.log");
sleep(3);
}
function signalHandler($signo)
{
switch($signo)
{
case SIGTERM:
{
system("echo 'SIGTERM caught!\n' >> /foo/foo.log");
exit();
}
case SIGINT:
{
system("echo 'SIGINT caught!\n' >> /foo/foo.log");
exit();
}
}
}
/etc/init.d/foo
# Source function library.
. /etc/rc.d/init.d/functions
php=${PHP-/usr/bin/php}
foo=${FOO-/foo/foo.php}
prog=`/bin/basename $foo`
lockfile=${LOCKFILE-/var/lock/subsys/foo}
pidfile=${PIDFILE-/var/run/foo.pid}
RETVAL=0
start() {
echo -n $"Starting $prog: "
daemon --pidfile=${pidfile} ${php} ${foo}
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${lockfile}
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
killproc -p ${pidfile} ${prog}
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
rh_status() {
status -p ${pidfile} ${foo}
}
# See how we were called.
case "" in
start)
rh_status >/dev/null 2>&1 && exit 0
start
;;
stop)
stop
;;
status)
rh_status
RETVAL=$?
;;
restart)
configtest -q || exit $RETVAL
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart|status}"
RETVAL=2
esac
exit $RETVAL
找到解决方案!
我能够通过将 stdout 和 stderr 重定向到 /dev/null
来使服务很好地进行守护进程
来自foolauncher.php
<?php
system('service foo start &> /dev/null');
似乎如我所愿!
运行 尝试在 Centos Linux 环境中守护 php 脚本时遇到一些问题。可惜Centos只有有限的daemon功能,没有start-stop-daemon...
我正在尝试创建一个持续运行 php 脚本的服务,直到捕获到信号。我也想要一个 php 脚本来启动服务。
- foolauncher.php 通过系统启动服务('service foo start')
- /etc/init.d/foo 开始 foo.php
- foo.php 生成 child 进程进行守护进程并 parent 退出
然而,当我启动 foolauncher.php 时,它显示 init.d 脚本启动我的 foo.php 服务,不释放终端,而是输出我的系统调用。当我发送 SIGINT 退出 parent 时,foo 服务也会停止 运行。
我知道问题出在foo.php:
$output = system('service foo status');
如果我省略系统调用的那一行,发送 SIGINT 退出 parent 将不会影响 foo 服务。
我知道 fclose(STDERR)、fclose(STDOUT) 和 fclose(STDIN),但我不确定我实际关闭这些输出的位置,因为它似乎会导致与发送类似的问题SIGINT 到 parent; foo.php 仍然同样死于系统调用。
好像是因为我正在向 STDOUT 输出一些东西,所以 parent 无法完全释放 child...我不打算使用其他的 deamonizing 方法(即. System Daemon, nohup), or using a cron job to execute (even he hard the daemonizing php is not a good idea), but a solution to how to solve this problem.
如有任何建议、建议或解决方案,我们将不胜感激!谢谢!
文件如下:
foolauncher.php:
<?php
system('service foo start');
foo.php:
<?php
declare(ticks = 1);
$pid = pcntl_fork();
if ($pid < 0)
{
system("echo 'failed to fork' >> /foo/foo.log");
exit;
}
else if ($pid)
{
system("echo 'parent exiting' >> /foo/foo.log");
exit;
}
$sid = posix_setsid();
if ($sid < 0)
{
exit;
}
pcntl_signal(SIGTERM, "signalHandler");
pcntl_signal(SIGINT, "signalHandler");
$daemonPid = posix_getpid();
system("echo 'Process started on $daemonPid!\n' >> /foo/foo.log");
system("echo $daemonPid > /var/run/foo.pid");
while(true)
{
// If I dont have this line, everything daemonizes nicely
$output = system("service foo status");
system("echo 'In infinite loop still! $output\n' >> /foo/foo.log");
sleep(3);
}
function signalHandler($signo)
{
switch($signo)
{
case SIGTERM:
{
system("echo 'SIGTERM caught!\n' >> /foo/foo.log");
exit();
}
case SIGINT:
{
system("echo 'SIGINT caught!\n' >> /foo/foo.log");
exit();
}
}
}
/etc/init.d/foo
# Source function library.
. /etc/rc.d/init.d/functions
php=${PHP-/usr/bin/php}
foo=${FOO-/foo/foo.php}
prog=`/bin/basename $foo`
lockfile=${LOCKFILE-/var/lock/subsys/foo}
pidfile=${PIDFILE-/var/run/foo.pid}
RETVAL=0
start() {
echo -n $"Starting $prog: "
daemon --pidfile=${pidfile} ${php} ${foo}
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${lockfile}
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
killproc -p ${pidfile} ${prog}
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
rh_status() {
status -p ${pidfile} ${foo}
}
# See how we were called.
case "" in
start)
rh_status >/dev/null 2>&1 && exit 0
start
;;
stop)
stop
;;
status)
rh_status
RETVAL=$?
;;
restart)
configtest -q || exit $RETVAL
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart|status}"
RETVAL=2
esac
exit $RETVAL
找到解决方案!
我能够通过将 stdout 和 stderr 重定向到 /dev/null
来使服务很好地进行守护进程来自foolauncher.php
<?php
system('service foo start &> /dev/null');
似乎如我所愿!