DEV Community

Jonathan Gonçalves
Jonathan Gonçalves

Posted on • Edited on

Adicionando o Laravel Horizon em nosso projeto

O Laravel Horizon simplifica a escalabilidade e configuração dos trabalhadores de fila, proporcionando um painel intuitivo e eficiente para o gerenciamento de filas no Laravel. Com métricas essenciais como taxa de transferência, tempo de execução e falhas, o Horizon facilita o monitoramento do sistema de filas.

Vamos fazer um exemplo prático utilizando o projeto product-api como base.

Product API

Easily start application with docker.

docker compose up
Enter fullscreen mode Exit fullscreen mode

Laravel Logo

Build Status Total Downloads Latest Stable Version License

About Laravel

Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:

Laravel is accessible, powerful, and provides tools required for large, robust applications.

Learning Laravel

Laravel has the most extensive and thorough documentation and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.

You may also try the Laravel Bootcamp, where you will be guided through building a modern Laravel…




Antes de prosseguir com o Laravel Horizon, é aconselhável possuir um bom entendimento sobre o uso de filas no Laravel.

Assumindo que você já tenha um bom entendimento sobre Laravel Queue, vamos começar.

Instale o Horizon no projeto.

composer require laravel/horizon
Enter fullscreen mode Exit fullscreen mode

Publique os assets.

php artisan horizon:install
Enter fullscreen mode Exit fullscreen mode

Agora, modifique o arquivo recém-criado config/horizon.php, incluindo a fila data_sync no array queue.

    'defaults' => [
        'supervisor-1' => [
            'connection' => 'redis',
            'queue' => ['default', 'data_sync'],
            'balance' => 'auto',
            'autoScalingStrategy' => 'time',
            'maxProcesses' => 1,
            'maxTime' => 0,
            'maxJobs' => 0,
            'memory' => 128,
            'tries' => 1,
            'timeout' => 60,
            'nice' => 0,
        ],
    ],
Enter fullscreen mode Exit fullscreen mode

A configuração atual atende aos jobs despachados para a fila data_sync. No entanto, se sua aplicação envia jobs mais extensos, pesados ou enfrenta picos de alta demanda, é aconselhável ajustar as configurações para otimizar o desempenho e garantir uma execução eficiente.

Imagine um cenário em que uma fila, lida com jobs demorados que podem levar até 5 minutos para processar.

Vamos configurar um novo supervisor para esse cenário.

        // example of a queue for processing long, heavy and high-demand jobs  
        'supervisor-2' => [
            'connection' => 'redis',
            'queue' => ['long_processing_jobs'],
            'balance' => 'auto',
            'autoScalingStrategy' => 'time',
            'maxProcesses' => 1,
            'maxTime' => 0,
            'maxJobs' => 0,
            'memory' => 128,
            'tries' => 3,
            'timeout' => 300,
            'nice' => 0,
        ],
Enter fullscreen mode Exit fullscreen mode

Atenção para retry_after em config/queue.php, ele deve ser maior que o timeout definido no supervisor de config/horizon.php.

        'long_processing_jobs' => [
            'driver' => 'redis',
            'connection' => 'default',
            'queue' => 'long_processing_jobs',
            'retry_after' => 450,
            'block_for' => null,
            'after_commit' => false,
        ],
Enter fullscreen mode Exit fullscreen mode

Vamos supor que durante picos de alta demanda, nossa fila de produção enfileira mais de 100 jobs em poucos minutos.

Para otimizar o desempenho da nossa fila, podemos ajustar os parâmetros maxProcesses e balanceMaxShift. Esses ajustes devem ser feitos considerando sempre os recursos disponíveis.

'environments' => [
    'production' => [
        'supervisor-2' => [
            'maxProcesses' => 20, // parallel processes
            'balanceMaxShift' => 4,
            'balanceCooldown' => 3,
            'tries' => 3,
        ],
    ],
],
Enter fullscreen mode Exit fullscreen mode

Podemos iniciar o Horizon com o comando abaixo.

php artisan horizon
Enter fullscreen mode Exit fullscreen mode

É recomendado o uso do Supervisor para gerenciar nosso processo do Horizon em produção, então vamos instala-lo.

sudo apt-get install supervisor
Enter fullscreen mode Exit fullscreen mode

Agora vamos criar um arquivo de configuração em /etc/supervisor/conf.d/horizon.conf.

[program:horizon]
process_name=%(program_name)s
command=php /home/jonathan/repo/product-api/artisan horizon
autostart=true
autorestart=true
user=jonathan
redirect_stderr=true
stdout_logfile=/home/jonathan/repo/product-api/storage/logs/horizon.log
stopwaitsecs=3600
Enter fullscreen mode Exit fullscreen mode

Altere command e stdout_logfile com o caminho da sua aplicação e user para seu usuario.

Crie o arquivo storage/logs/horizon.log dentro da sua aplicação.

Inicie o Supervisor.

// System V
sudo service supervisor start

// Systemd
sudo systemctl start supervisor
Enter fullscreen mode Exit fullscreen mode

Você poderá ver o log do Horizon em storage/logs/horizon.log e o log do Supervisor em /var/log/supervisor/supervisord.log.

Com as filas e supervisores do Horizon configurados e o Supervisor gerenciando o processo do Horizon, vamos rodar nossa aplicação product-api.

PHP_CLI_SERVER_WORKERS=2 php artisan serve --port 8001
Enter fullscreen mode Exit fullscreen mode

Vamos requisitar o endpoint que despacha o job de sinc de dados.

curl http://localhost:8001/api/v1/sync/plataform1/products
Enter fullscreen mode Exit fullscreen mode

Podemos acessar o dashboard do Horizon para acompanhar tudo com métricas detalhadas em http://localhost:8001/horizon.

Horizon Dashboard

Você pode ajustar app/Providers/HorizonServiceProvider.php para que apenas usuários especificos vejam o dashboard em ambiente não local.

protected function gate(): void
{
    Gate::define('viewHorizon', function (User $user) {
        return in_array($user->email, [
            'jonathan@example.com',
        ]);
    });
}
Enter fullscreen mode Exit fullscreen mode

Ao tentar acessar com qualquer outro usuário, o forbidden status é retornado.

Forbidden Status

Ao longo deste artigo, exploramos as vantagens do Laravel Horizon para simplificar a gestão de filas no Laravel, destacando métricas essenciais. Com o exemplo prático no projeto Product-API, aprendemos a otimizar a escalabilidade e configurar trabalhadores de fila de maneira eficiente.

Top comments (0)