Thiago Cantero

Tecnologia e Entretenimento

Banco de DadosLaravelPHPProgramaçãoSistemas Operacionais

Como agendar tarefas com Laravel.

Olá, mundo!Tudo bem?

Estava um pouco sem tempo devido os estudos, e o trabalho, impossibilitando de atualizar o Blog aqui com algumas dicas, reflexões, e outros assuntos de interesse no ramo de tecnologia e afins. Estava em uma rotina bem difícil para tal disponibilidade de tempo, agora estamos de volta novamente! ; )

Introdução

Quando necessitamos executar uma tarefa específica de nossa aplicação, ou até mesmo uma fila, ou ainda uma rotina de ETL, por exemplo, podemos automatizar com cron. Você pode usar scripts bash nativos como powershell (em ambientes windows), bash shell (ambientes unix-like), mas neste exemplo vamos utilizar o Laravel. Atuando como um driver entre o Sistema Operacional e o PHP.

Para nosso exemplo, faremos a chamada do mysqldump para fazer um backup de uma base de dados no MariaDB, importante configurar o arquivo de ambiente do seu projeto laravel .env para colocar o nome do usuário/senha e a base de dados que queira fazer esta rotina de backup.

Vamos ao Trabalho//

Iniciamos uma nova instalação do Laravel:

$ composer create-project laravel/laravel laravel-cron

Com o projeto criado, entramos na pasta e vamos criar o nosso Comando que executaremos com agendamento:

 

$ php artisan make:command TesteCron --command=teste:cron

app/Console/Commands/TesteCron.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Carbon\Carbon;

class TesteCron extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'teste:cron';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Executa agendamento de algum Comando específico';

    /**
     * Execute the console command.
     */
    public function handle(): void
    {
        $arquivo = "backup-". Carbon::now()->format('d-m-Y'). ".gz";

        $comando = "mysqldump --user=" . env('DB_USERNAME') .
        " --password=" . env('DB_PASSWORD') . 
        " --host=" . env('DB_HOST') . " " 
        . env('DB_DATABASE') . "  | gzip > " 
        . storage_path() . "/app/backup/" . $arquivo;

        $returnVar = NULL;
        $output  = NULL;
  
        exec($comando, $output, $returnVar);


    }
}

Como podemos observar, temos a propriedade protegida $signature que será chamado o alias de nosso comando, seguindo de $description que será a descrição de nosso comando.

No método handle() temos nossa rotina de backup, em que iremos tem um pré-nome backup, concatenando com o dia, mês e ano em formato gunzip. Passamos para a variável $comando executar o mysqldump, injetando as variáveis de ambiente já previamente configuradas. E ao final executamos. Importante criarmos  pasta backup: /storage/app/backup.

Nosso próximo passo será de configurar o Kernel do Console Laravel para execução de nosso Comando.
Importante que você pode definir uma série de estratégias para execução de sua tarefa, veja esta breve lista:

Método Descrição
->cron('*
* * * *');
Executa a tarefa de maneira customizada
->everyMinute(); Executa a tarefa a cada minuto
->everyTwoMinutes(); Executa a tarefa a cada dois minutos
->everyThreeMinutes(); Executa a tarefa a cada três minutos
->everyFourMinutes(); Executa a tarefa a cada quatro minutos
->everyFiveMinutes(); Executa a tarefa a cada cinco minutos
->everyTenMinutes(); Executa a tarefa a cada dez minutos
->everyFifteenMinutes(); Executa a tarefa a cada quinze minutos
->everyThirtyMinutes(); Executa a tarefa a cada trinta minutos
->hourly(); Executa a tarefa a cada hora
->everyOddHour(); Executa a tarefa a cada hora impar
->everyTwoHours(); Executa a tarefa a cada duas horas
->everyThreeHours(); Executa a tarefa a cada três horas
->everyFourHours(); Executa a tarefa a cada quatro horas
->everySixHours(); Executa a tarefa a cada seis horas
->daily(); Executa a tarefa todas as noites à meia noite
->dailyAt('11:00'); Executa a tarefa todos os dias às 11h00 da manhã
->twiceDaily(9,13); Executa a tarefa diariamente em dois horários pré-definidos, neste exemplo 09h00 da manhã e 13h00.
->weekly(); Executa a tarefa todos os sábado à meia noite
->weeklyOn(1,
'
10:00');
Executa a tarefa todas as segundas-feiras às 10h00
->monthly(); Executa a tarefa mensalmente, no primeiro dia do mês à meia noite
->monthlyOn(6,
'15:00');
Executa a tarefa todo o dia do mês, neste exemplo dia 06 às 15h00
->timezone('America/Sao_Paulo'); Define a região para a Data

app/Console/Kernel.php

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     */
    protected function schedule(Schedule $schedule): void
    {
         $schedule->command('teste:cron')->everyFiveMinutes();
    }

    /**
     * Register the commands for the application.
     */
    protected function commands(): void
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

Nosso comando é chamado na função schedule neste caso, a cada cinco minutos. A base de dados é pequena demais, e o espaço em disco não será afetado! ; )

Agora vamos testar nosso Comando:

$ php artisan

Como já podemos observar, nosso Comando já foi incluso no rol dos Comandos do Artisan.

Façamos o teste executando nosso comando, através do Drive Schedule do Artisan:

$ php artisan schedule:run

O arquivo foi criado:

E podemos ver que o Kernel Console do Artisan gerencia o funcionamento da execução do Comando:

$ php artisan schedule:list

Com estes passos bem definidos, agora devemos programar nosso agendador para executar de maneira automática nosso script.

Como eu uso unix-like (Linux), vou usar o crontab.

$ crontab -e
* * * * * cd /diretório-do-seu-projeto && php artisan schedule:run >> /dev/null 2>&1

 

Por hoje é só, até breve! ; )

Código Fonte no Github.

 

Tente mover o mundo – o primeiro passo será mover a si mesmo.