Do not speak Portuguese? Translate this site with Google or Bing Translator
Queues no Laravel (Filas)

Posted on: June 25, 2020 12:17 AM

Posted by: Renato

Categories: Laravel

Views: 2026

Queues no Laravel (Filas)

Imagine uma aplicação recebendo uma demanda muito grande de solicitações simultaneamente ao mesmo tempo, e mais do que isso, o processo solicitado é algo pesado, ou seja, tem um tempo de processamento demorado, e o time de resposta é demorado, como por exemplo um envio de e-mail. Imaginou?

Se sua aplicação precisar processar algo pesado (que o tempo de resposta é grande) o ideal é liberar o usuário, ou seja, não travar a aplicação, e executar essa tarefa durante o tempo ocioso do servidor. Além de melhorar a usabilidade da aplicação, por não travar no momento de fazer aquela determinada requisição, isso ainda ajuda a economizar “recursos” do servidor, e trabalhar de forma mais inteligente sem sobrecarregar com múltiplos processos simultâneos.

 

Ah, mas como fazer isso?

Filas (Queues)! O Laravel tem recursos nativos para trabalhar com processos usando filas. Esse recurso permite o sistema executar tarefas de forma sequencial, sem sobrecarregar a aplicação com múltiplos processos simultâneos.
Quando adiciona uma tarefa na fila (queue) define uma sequência exata para o processamento das tarefas (que pode ser enviar um e-mail, registrar log, escrever em um arquivo e etc), e isso garante que o processador não fique executando múltiplas tarefas paralelas, e com isso resulta em um melhor aproveitamento dos recursos do server.

 

Queues na Prática
O arquivo de configuração de filas no Laravel fica em config/queue.php

Os formatos de drivers suportados são: database, Beanstalkd, Amazon SQS, Redis, sync (processamento imediato), e null.

 

Queues database:
Nesse exemplo vamos trabalhar com o driver database, precisamos criar uma tabela, que vai conter todos as tarefas que devem ser executadas (processadas), e a medida que são processadas são descartadas do banco de dados.

Para criar a estrutura da tabela (arquivo de migration) deve rodar o comando:


php artisan queue:table
Esse comando vai criar o arquivo de migration: database/migrations/timestamps_aqui_create_jobs_table.php que contém a estrutura da tabela jobs, que é a tabela que contém a estrutura das queues que precisarão ser processadas.

Após criar a migration o próximo passo é obviamente criar a tabela, a partir da migration, para isso rode o comando:


php artisan migrate
Agora que decidimos que o formato de processamento das filas será por database, precisa alterar as configurações setando essa opção. No arquivo config/queue.php fica essas configurações, precisamos alterar o valor de “default” para definir essa configuração, por padrão (default) está definido como sync, neste caso precisamos alterar para database, observe que está pegando essa informação do arquivo .env:


'default' => env('QUEUE_DRIVER', 'sync'),
Então vamos alterar no arquivo .env o QUEUE_DRIVER para database:


QUEUE_DRIVER=database
Quando definimos nosso QUEUE_DRIVER para database, vai pegar as configurações do arquivo config/queue.php em connections > database:


'connections' => [
    // [...]
 
    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 90,
    ],
 
    // [...]
],
 

Jobs:
Existem N formas de executar algum processo com Queues (filas), uma delas é criar uma classe especifica para fazer o processo de filas.

Jobs são classes que ficam armazenadas em app/Jobs/ e são processadas pelo sistema de Queues do Laravel.
Para criar uma nova classe de JOB rode este comando:

1
php artisan make:job SendWelcomeEmail
Essa classe que foi gerada, implementa a interface Illuminate\Contracts\Queue\ShouldQueue, para que o processamento seja realizado usando queue.

 

Enviando e-mail de boas vindas:
Nesse exemplo vamos enviar um e-mail de boas vindas ao usuário que acabou de se cadastrar no sistema, veja como fica a implementação da nossa classe de JOB SendWelcomeEmail:

namespace App\Jobs;
 
use Illuminate\Support\Facades\Mail;
use App\Mail\WelcomeEmail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
 
class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
    private $user;
 
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }
 
    /**
     * Execute the job.
     *
     * @param  User  $user
     * @return void
     */
    public function handle()
    {
        // Send email welcome user
        Mail::to($this->user->email)
                ->send(new WelcomeEmail($this->user));
    }
}
O método construtor em nossa classe espera um objeto com os dados do usuário que acabou de ser cadastrado. Já no método handle() é onde fica o processamento.

O próximo passo é criar a classe para o envio de e-mail WelcomeEmail:

1
php artisan make:mail WelcomeEmail
Nessa classe vamos passar o objeto do usuário que acabou de ser cadastrado:

1
namespace App\Mail;
 
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;
 
    private $user;
 
    /**
     * Create a new message instance.
     *
     * @param  User  $user
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }
 
    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.created.welcome')
                    ->subject('Boas Vindas!!!')
                    ->with([
                        'user' => $this->user,
                    ]);
    }
}
Observe que neste exemplo estamos usando uma view com Markdown, então precisamos criar a view com a sua estrutura (resources/views/emails/created/welcome.blade.php):


@component('mail::message')
# Boas Vindas
 
Seja muito bem vindo a nossa plataforma 🙂
 
@component('mail::button', ['url' => config('app.url')])
Acessar o Site
@endcomponent
 
Obrigado,
{{ config('app.name') }}
@endcomponent
OBS: Para configurações de e-mail em ambiente de desenvolvimento, sugiro o Mailtrap.io (leia sobre!)
O JOB está pronto, a classe de envio de e-mails também, agora nos resta disparar o JOB.

 

Dispatching Jobs:
Para disparar (rodar/processar) o JOB a implementação é a seguinte:

1
NameJob::dispatch($object);
Nesse exemplo só vamos disparar o JOB para rodar a fila (queue) quando um novo usuário se registrar, para conseguir fazer isso precisamos trabalhar com os Observers do Laravel, para monitorar um novo cadastro e disparar o nosso JOB que vai enviar o e-mail de boas vindas.

Vamos criar um Observer que vai monitorar o evento de created (usuário cadastrado), para isso rode este comando:

1
php artisan make:observer UserObserver --model=User
Criou um novo arquivo de classe em em app/Observers/UserObserver.php

Um Observer é possível monitorar alguns eventos do usuário, como created (usuário registrado), updated (usuário editado), deleted (usuário deletado). Neste caso o que nos interessa é o created, veja como fica a implementação:


namespace App\Observers;
 
use App\Jobs\SendWelcomeEmail;
use App\Models\User;
 
class UserObserver
{
    /**
     * Handle to the user "created" event.
     *
     * @param  \App\User  $user
     * @return void
     */
    public function created(User $user)
    {
        // Dispatching Job SendWelcomeEmail
        SendWelcomeEmail::dispatch($user);
    }
 
    // [...]
}
O próximo passo é registrar o Observer no Provider AppServiceProvider (app/Providers/AppServiceProvider.php):


namespace App\Providers;
 
use App\Models\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        User::observe(UserObserver::class);
    }
 
    // [...]
}
 

Rodar Queues no Laravel:
Se registrar um novo usuário nada vai acontecer, mas por que? Porque falta executar os jobs (as queues que precisam ser executadas). Se observar na tabela jobs (que foi criada mais acima) ela consta esse registro, agora falta processar.

Para processar as filas (queues) rode este comando:

php artisan queue:work
Pouco tempo depois os e-mails de boas vindas começam a chegar aos respectivos usuários.

OBS: Muitas camadas dentro do Laravel permitem trabalhar com Queues diretamente nelas, como E-mails, Eventos, Notifications e etc. Para esses casos basta a classe implementar a interface Illuminate\Contracts\Queue\ShouldQueue


1

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

OUTROS (16) Variados (109) PHP (133) Laravel (171) Black Hat (3) front-end (29) linux (114) postgresql (39) Docker (28) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (56) devops (25) nodejs (5) npm (3) nvm (1) git (8) firefox (1) react (7) reactnative (5) collections (1) javascript (7) reactjs (8) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (2) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (12) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (5) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (3) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (43) Kubernetes (3) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (2) jwt (5) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (3) Architecture (4) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (2) autorizacao (2) authentication (4) authorization (3) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1) Axios (1) Fetch (1) Deepin (1) vue (4) nuxt (1) PKCE (1) Oauth2 (2) webhook (1) TypeScript (1) tailwind (1) gource (2)

New Articles



Get Latest Updates by Email