catthr
7/17/2015 - 10:05 PM

Очереди в OctoberCMS laravel Настройка supervisor

Очереди в OctoberCMS laravel Настройка supervisor

  • Команда artisan для создания команды не работает
  • В плагине определим 2 папки - Commands и Handlers/Commands
  • Добавляем с соответствующим namespace
  • Чтобы для команды нашелся обработчки, нужно добавить маппинг.

Запуск слушателя, можно запустить несколько

php artisan queue:listen
php artisan queue:listen && php artisan queue:listen && php artisan queue:listen

** Отличие listen & work **

queue:work - выполняет одну задачу из очереди и прекращает работу

queue:work --daemon - выполняет задачи по очереди, не перезагружая фреймворк, тем самым сильно снижает нагрузку на CPU. Все ресурсы освобождать самостоятельно.

queue:listen - выполняет задачи по очереди, каждый раз загружая ларавел с начала.

В доках указано, что надо использовать DB::reconnect(), так как со временем соедение закрывается mysql, но в issue на гитхабе автор пишет, что соедине6ние само отловит эту ошибку и переконнектится при необходимости.

После обновление кода нужно запускать queue:restart, чтобы загрузились новые версии фреймворка

У work нет параметра timeout, длительность выполнения зависит от php параметра max_execution_time

** Параметры **

По умолчанию слушается очередь default, лругие очереди указываются явно, можно через запятую

php artisan queue:listen --queue=import

Очень важный параметр tries- количество попыток, иначе задание с ошибкой будет выполнятьсмя снова и снова

php artisan quque:listen --queue=import --tries=3

Пауза перед следующей задачей sleep, если задач в очереди нет, в секундах

php artisan queue:listen --sleep=5

Чтобы не завершались по timeout

php artisan queue:listen --timeout=0

Кроме timeout есть свойствоexpire`, по истечению которого задача считается просроченной и ее снова можно брать из очереди. Таким образом, олна и та же задача может начатьвыполняться несколько раз. Поу молчанию, 60 секунд. Настраивается в конфиге

 'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'expire' => 600,
        ],
namespace Develex\Estate\Commands;

use Develex\Estate\Models\Estate;
use Illuminate\Console\Command;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class LandImage extends Command implements ShouldBeQueued
{
    use InteractsWithQueue, SerializesModels;

    /**
     * Create a new command instance.
     *
     * @return void
     */

    public $object;
    public $urls;

    public function __construct(Estate $obj, $urls)
    {
        $this->object = $obj;
        $this->urls = $urls;
    }
}
namespace Develex\Estate\Handlers\Commands;

use Develex\Estate\Commands\LandImage;
use System\Models\File;

class ImageHandler
{
    /**
     * Create the command handler.
     *
     * @return void
     */

    public function __construct()
    {
    }

    /**
     * Handle the command.
     *
     * @param  LandImage  $command
     * @return void
     */
    public function handle(LandImage $command)
    {
        foreach($command->urls as $img){
            $file = new File();
            $filename_from_url = parse_url($img);
            $ext = pathinfo($filename_from_url['path'], PATHINFO_EXTENSION);
            copy(str_replace(' ', '%20', $img), 'temp.' . $ext);
            $file->fromFile('temp.' . $ext);
            $file->save();

            $command->object->images()->add($file);
        }

    }
}
   public function boot(){
        $dispatcher = $this->app->make('Illuminate\Bus\Dispatcher');
        // Конкретный маппинг
        $dispatcher->maps(['Develex\Estate\Commands\LandImage' => 'Develex\Estate\Handlers\Commands\ImageHandler@handle']);
        // Указываем namespace, в этом случае обработчик должен иметь название - названиеКомандыHandler
        $dispatcher->mapUsing(function($command)
        {
            return Dispatcher::simpleMapping(
                $command, 'Develex\Estate\Commands', 'Develex\Estate\Handlers\Commands'
            );
        });
    }
  1. Установить supervisor
sudo apt-get install supervisor
  1. Добавить файл конфигурации
cd /etc/supervisor/conf.d
touch laravel_queue.conf
  1. Добавить информацию о запускаемых процессах
[program:queue_images]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/web/sites/-/artisan queue:listen --timeout=0 --tries=3
autostart=true
autorestart=true
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/web/sites/-/storage/logs/worker.log
[program:queue_watermarks]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/web/sites/-/artisan queue:listen --queue=watermarks --timeout=0 --tries=3
autostart=true
autorestart=true
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/web/sites/-/storage/logs/worker.log
  1. Нужно перечитать конфигурацию и перезапустить
supervisorctl reread
supervisorctl update

Посмотреть запущенные процессы:

supervisorctl
  1. Можно настроить веб-интерфейс. Добавить в конфигурационный файл /etc/supervisord.conf
[inet_http_server]
port = 9001
username = user # Basic auth username
password = pass # Basic auth password
// Помещает задачу в очередь. Модели Eloquent можно передавать объектами (не id), они будут сериализованны в id + класс
\Queue::push(new LandImage($land, $urls));