我的 Symfony 2.3 项目中有一个类正在执行一些 http 请求并且需要一些时间。
我想将此任务作为后台进程运行,以便服务器向客户端返回答案,并且后台进程继续运行。
你知道如何在 Symfony 中做到这一点吗?
我找到了流程组件:http ://symfony.com/doc/current/components/process.html但我不确定是否可以从那里运行类方法。
我的 Symfony 2.3 项目中有一个类正在执行一些 http 请求并且需要一些时间。
我想将此任务作为后台进程运行,以便服务器向客户端返回答案,并且后台进程继续运行。
你知道如何在 Symfony 中做到这一点吗?
我找到了流程组件:http ://symfony.com/doc/current/components/process.html但我不确定是否可以从那里运行类方法。
一个简单的方法是通过使用队列和 symfony 命令来处理队列,将繁重的工作从响应中分离出来。
http://symfony.com/doc/current/components/console/introduction.html
创建一个 symfony 命令来处理添加到队列中的作业,然后将要完成的工作从控制器添加到队列中。队列可能会被实现为作业的数据库表。
这样,您可以向用户返回成功响应,并定期在服务器上运行 cron 作业来处理您需要的工作。
这是您可以使用enqueue库轻松完成的事情。首先,您可以从多种传输方式中进行选择,例如 AMQP、STOMP、Redis、Amazon SQS、Filesystem 等。
其次,它超级好用。让我们从安装开始:
您必须安装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 扩展,但它的性能是惊人的。