2013-11-22 53 views

回答

7

一個簡單的方法是通過使用隊列和symfony命令來處理隊列來將繁重的工作從響應中分離出來。

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

創建處理的作業添加到隊列中的命令symfony中,然後加入從你的控制器做隊列中的工作。該隊列可能會作爲作業的數據庫表來實施。

通過這種方式,您可以將成功響應返回給用戶,並定期在服務器上運行cron作業以處理所需的工作。

+0

謝謝喬恩,今天我會試試。爲你+1。 –

+0

工人的Cron使用是一件危險的事情。考慮一下:你用cron每分鐘運行一個工人,但工人需要一分多鐘才能完成這項工作。你結束了很多進程競爭資源,降低了整體性能。服務器可能會關閉。 –

0

這是你可以很容易地用enqueue圖書館做的事情。首先,您可以從各種transports中進行選擇,例如AMQP,STOMP,Redis,Amazon SQS,Filesystem等。其次,這是超級簡單易用的。我們從安裝開始:

您必須安裝enqueue/enqueue-bundle庫和one of the transports。假設你選擇文件系統enqueue/fs庫:

composer require enqueue/enqueue-bundle enqueue/fs 

現在讓我們看看如何從您的文章腳本發送消息:

<?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:消費--setup-broker -vvv

在prod上,您最有可能需要多個消費者,並且如果該過程存在,則必須重新啓動。爲了解決這個問題,你需要一個流程管理器。有幾種選擇:

http://supervisord.org/ - 您需要額外的服務。它必須正確配置。 這是一個純PHP過程管理器。基於Symfony流程組件和純PHP代碼。它可以處理重啓進程,糾正sigterm信號退出等等。 這是一個php \ swoole過程管理器。它需要一個swoole PHP擴展,但性能是驚人的。