我在我的Symfony 2.3項目中有一個類正在做一些http請求,需要一些時間。Symfony2和後臺進程
我想將此任務作爲後臺進程運行,以便服務器向客戶端返回一個答案,後臺進程將繼續運行。
你知道在Symfony中怎麼做?
我發現過程組件:http://symfony.com/doc/current/components/process.html但我不確定是否可以從那裏運行類方法。
我在我的Symfony 2.3項目中有一個類正在做一些http請求,需要一些時間。Symfony2和後臺進程
我想將此任務作爲後臺進程運行,以便服務器向客戶端返回一個答案,後臺進程將繼續運行。
你知道在Symfony中怎麼做?
我發現過程組件:http://symfony.com/doc/current/components/process.html但我不確定是否可以從那裏運行類方法。
一個簡單的方法是通過使用隊列和symfony命令來處理隊列來將繁重的工作從響應中分離出來。
http://symfony.com/doc/current/components/console/introduction.html
創建處理的作業添加到隊列中的命令symfony中,然後加入從你的控制器做隊列中的工作。該隊列可能會作爲作業的數據庫表來實施。
通過這種方式,您可以將成功響應返回給用戶,並定期在服務器上運行cron作業以處理所需的工作。
這是你可以很容易地用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擴展,但性能是驚人的。
謝謝喬恩,今天我會試試。爲你+1。 –
工人的Cron使用是一件危險的事情。考慮一下:你用cron每分鐘運行一個工人,但工人需要一分多鐘才能完成這項工作。你結束了很多進程競爭資源,降低了整體性能。服務器可能會關閉。 –