从symfony / console启动后台symfony /进程

时间:2015-03-13 16:56:55

标签: php symfony symfony-console symfony-process

我试图创建一个cli(symfony / console)来管理使用消息队列的长时间运行的子进程(symfony / process)。我有两个命令,Consume和Listen。 Consume是Listen的包装器,因此它可以在后台运行。 Listen是一个长期运行的MQ转储,它会在消息队列中添加消息时显示其他消息。

问题:当尝试从消耗中调用侦听的cli命令时,它会启动进程并给我一个PID,但子进程会立即死掉。我需要弄清楚如何让Consume分离掉多个实际保持运行的Listen进程。

如果相关,运行的操作系统是使用PHP 5.5的SLES 12和Ubuntu 14.04。

部分代码(相关摘要)


收听

// Runs as: php mycli.php mq:listen
// Keeps running until you ctrl+C
// On the commandline, I can run this as
// nohup php mycli.php mq:listen 2>&1 > /dev/null &
// and it works fine as a long running process.
protected function execute(InputInterface $input, OutputInterface $output)
{
    $mq = new Mq::connect();

    while (true) {
        // read the queue
        $mq->getMessage();
    }
}

消费

// Runs as: php mycli.php mq:consume --listen
// Goal: Run the mq:listen command in the background
protected function execute(InputInterface $input, OutputInterface $output)
{   
    if ($input->getOption('listen')) {

        $process = new Process('php mycli.php mq:listen');

        $process->start();

        $pid = $process->getPid();
        $output->writeln("Worker started with PID: $pid");

    }
}

1 个答案:

答案 0 :(得分:2)

这样的任务通常会被委托给像Supervisor这样的任务调度程序。将进程留作这样的孤儿是非常危险的。如果您的消息队列客户端失去连接但进程仍在运行,它们将有效地变成僵尸。

您需要在每个子流程的持续时间内保持mq:consume命令运行。这可以实现,如前三个例子所示:http://symfony.com/blog/new-in-symfony-2-2-process-component-enhancements