Symfony2和后台进程

3
我在我的Symfony 2.3项目中有一个类,它执行一些HTTP请求并需要一定的时间。我想把这个任务作为后台进程运行,这样服务器就会向客户端返回一个响应,而后台进程继续运行。您知道如何在Symfony中实现这个功能吗?我找到了Process组件:http://symfony.com/doc/current/components/process.html,但我不确定是否可以从那里运行一个类方法。
2个回答

7
一种简单的方法是通过使用队列和Symfony命令将繁重的工作与响应分离。创建一个Symfony命令来处理添加到队列中的作业,然后从控制器将需要完成的工作添加到队列中。队列很可能被实现为作业数据库表。这样你就可以向用户返回成功响应,并在服务器上定期运行cron作业以处理所需的工作。更多信息请参考:http://symfony.com/doc/current/components/console/introduction.html

谢谢Jon,我今天会尝试一下。给你点赞。 - Milos Cuculovic
使用 Cron 调度工作进程是一件危险的事情。想象一下:您通过 Cron 每分钟运行一个工作进程,但是该工作进程需要超过一分钟才能完成任务。这样会导致有很多进程争夺资源,从而降低了整体性能。服务器可能会完全崩溃。 - Maksim Kotlyar

0

这是你可以轻松使用 enqueue 库完成的事情。首先,你可以从多种传输方式中选择,例如 AMQP、STOMP、Redis、Amazon SQS、文件系统等。

其次,它非常容易使用。让我们从安装开始:

你需要安装 enqueue/enqueue-bundle 库和其中一种传输方式。假设你选择了文件系统enqueue/fs库:

composer require enqueue/enqueue-bundle enqueue/fs 

现在让我们看看如何从您的POST脚本发送消息:

<?php

use Enqueue\Client\ProducerInterface; 
use Symfony\Component\DependencyInjection\Container;

/** @var Container $container */

/** @var ProducerInterface $producer */ $producer = $container->get('enqueue.client.producer');

$producer->sendCommand('a_background_task', 'task_data');

对于消费,您需要创建一个处理器服务,并使用enqueue.client.processor标记进行标记:

<?php

use Enqueue\Client\CommandSubscriberInterface;
use Enqueue\Psr\PsrContext;
use Enqueue\Psr\PsrMessage;
use Enqueue\Psr\PsrProcessor;

class BackgroundTask implements PsrProcessor, CommandSubscriberInterface
{
    public static function getSubscribedCommand()
    {
        // do job

        return self::ACK;
    }

    public function process(PsrMessage $message, PsrContext $context)
    {
        return 'a_background_task';
    }
} 

使用以下命令运行消费者:

./bin/console enqueue:consume --setup-broker -vvv

在生产环境中,您很可能需要多个消费者,并且如果进程存在,则必须重新启动。为了解决这个问题,您需要一种进程管理器。有几个选项:

http://supervisord.org/ - 您需要额外的服务。它必须正确配置。 像这样的纯PHP进程管理器。基于Symfony进程组件和纯PHP代码。它可以处理进程重启,在sigterm信号上正确退出等等。 像这样的php\swoole进程管理器。它需要一个swoole PHP扩展,但其性能非常出色。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接