如何实现异步队列在Symfony 3中运行Method

时间:2017-06-27 15:10:47

标签: php symfony asynchronous

首先,关于我的项目的一些基本信息:我有一个使用Symfony 3构建的网站。对于某些任务,我考虑实现运行异步PHP方法。有些事件需要花费大量时间,但结果不一定非常明显。

例如:在方法newOrder中,我有一些函数addUserLTV,它只执行几个步骤。客户无需等待所有步骤完成,只需在基本操作后立即获得确认 - ' newOrder'将addUserLTV添加到队列并立即显示确认(已完成运行)。 当服务器有时间执行时,将运行队列任务。

public function addUserLTV( $userID, $addLTV )
{ //same code
}

怎么做?在交响乐3中有可能吗?

1 个答案:

答案 0 :(得分:11)

您可以使用this pull request轻松完成此操作。关于你为什么要选择它的几句话:

  • 它支持enqueue bundle从最简单的(文件系统)到企业的(RabbitMQ或Amazon SQS)。
  • 它带有非常强大的a lot of transports
  • 它具有顶级抽象,可以非常轻松地使用。
  • 还有更多可能派上用场的东西。

关于你的问题。以下是如何使用enqueue bundle执行此操作的方法。关注bundle

现在addUserLTV方法如下所示:

<?php
namespace Acme;

use Enqueue\Client\ProducerInterface;

class AddUserLTVService
{
    /**
     * @var ProducerInterface
     */
    private $producer;

    /**
     * @param ProducerInterface $producer
     */
    public function __construct(ProducerInterface $producer)
    {
        $this->producer = $producer;
    }

    public function addUserLTV( $userID, $addLTV )
    {
        $this->producer->sendCommand('add_user_ltv', [
            'userId' => $userID, 
            'ltv' => $addLTV]
        );
    }
}

它使用客户端将消息发送到消息队列(我之前提到的顶级抽象)。该服务必须注册到Symfony容器:

services:
    Acme\AddUserLTVService: 
        arguments: ['@enqueue.producer']

现在让我们来看看消费方面。您需要一个执行此任务的命令处理器:

<?php
namespace Acme;

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

class AddUserTVAProcessor implements PsrProcessor, CommandSubscriberInterface
{
    public function process(PsrMessage $message, PsrContext $context)
    {
        $data = JSON::decode($message->getBody());

        $userID = $data['userID'];
        $addLTV = $data['ltv'];

        // do job

        return self::ACK;
    }

    public static function getSubscribedCommand()
    {
        return 'add_user_ltv';
    }
}

将其注册为具有enqueue.client.processor标记的服务:

services:
    Acme\AddUserTVAProcessor: 
        tags:
            - {name: 'enqueue.client.processor'}

它用于编码。运行消耗命令,您就完成了:

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