php - 在 Centos 上守护 php 脚本

标签 php linux daemon

尝试在 Centos Linux 环境中守护 php 脚本时遇到一些问题。可惜Centos只有有限的daemon功能,没有start-stop-daemon...

我正在尝试创建一个持续运行 php 脚本的服务,直到捕获到信号。我也想要一个 php 脚本来启动服务。

  • foolauncher.php 通过 system('service foo start') 启动服务
  • /etc/init.d/foo 启动foo.php
  • foo.php 产生子进程守护进程和父进程退出

但是,当我启动 foolauncher.php 时,它显示 init.d 脚本启动了我的 foo.php 服务,并没有释放终端,而是输出了我的系统调用。当我发送 SIGINT 退出父进程时,foo 服务也停止运行。

我知道问题出在foo.php:

$output = system('service foo status');

如果我省略系统调用的那一行,发送 SIGINT 退出父级将不会影响 foo 服务。

我知道 fclose(STDERR)、fclose(STDOUT) 和 fclose(STDIN),但我不确定我实际关闭这些输出的位置,因为它似乎会导致与向 SIGINT 发送 SIGINT 类似的问题 parent ; foo.php 仍然同样在系统调用时死掉。

似乎因为我正在向 STDOUT 输出一些东西,所以父级无法完全释放子级......我不打算使用其他 deamonizing 方法(即 System Daemon,nohup),或使用要执行的 cron 作业(尽管我听说将 php 守护进程不是一个好主意),但是解决这个问题的方法。

如有任何建议、建议或解决方案,我们将不胜感激!谢谢!

文件如下:

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 "$1" 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');

似乎在做我想做的事!

关于php - 在 Centos 上守护 php 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29152473/

相关文章:

Java 应用程序作为 Windows 服务

php - 如何从 codeigniter 中的数据库表中获取特定值

php - 声明: UPDATE `blog_posts` SET `visit` = `visit` + 1 WHERE `id` = 14155 ORDER BY id LIMIT 1

linux - SHELL转TXT,可以吗?

c# - 如何使用 .Net Core 在 Linux 上获取当前执行目录?

daemon - 如何使用 Aria2c RPC 服务器作为守护进程?

javascript - 按钮不调用脚本 - onclick 方法

php - 如何通过 PHP 更改 php.ini?

linux - 使用 cat 和 grep 打印行及其编号但同时忽略空行

java - 是否可以对 Apache Spark 中的所有工作人员执行命令?