【问题标题】:Symfony2 and Background processesSymfony2 和后台进程
【发布时间】:2013-11-22 14:26:07
【问题描述】:

我的 Symfony 2.3 项目中有一个类正在执行一些 http 请求并且需要一些时间。

我想将此任务作为后台进程运行,以便服务器向客户端返回应答,后台进程继续运行。

你知道如何在 Symfony 中做到这一点吗?

我找到了流程组件:http://symfony.com/doc/current/components/process.html,但我不确定是否可以从那里运行类方法。

【问题讨论】:

    标签: php symfony process background symfony-process


    【解决方案1】:

    一个简单的方法是通过使用队列和 symfony 命令来处理队列,从而将繁重的工作与响应分开。

    http://symfony.com/doc/current/components/console/introduction.html

    创建一个 symfony 命令来处理添加到队列中的作业,然后将要完成的工作从控制器添加到队列中。队列可能会被实现为作业的数据库表。

    这样您就可以向用户返回成功响应,并定期在服务器上运行 cron 作业来处理您需要的工作。

    【讨论】:

    • 谢谢乔恩,我今天会试试。为你 +1。
    • 工人使用 Cron 是一件危险的事情。考虑一下:您通过 cron 每分钟运行一个工作人员,但工作人员需要超过一分钟才能完成这项工作。您结束了许多进程竞争资源,从而降低了总体性能。服务器可能完全宕机了。
    【解决方案2】:

    使用enqueue 库可以轻松做到这一点。首先,您可以从多种transports中进行选择,例如AMQP、STOMP、Redis、Amazon SQS、Filesystem等。

    其次,它超级好用。让我们从安装开始:

    您必须安装enqueue/enqueue-bundle 库和one of the transports。假设你选择文件系统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

    在 prod 上,您很可能需要不止一个消费者,如果存在该流程,则必须重新启动它。为了解决这个问题,您需要一种流程管理器。有几种选择:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多