Laravel Queue (Kuyruk)

Laravel ile yapılan projelerde bazen işlemleri kuyruklamak gerekebiliyor. Yapılacak işlemin sonucunu response dönmek gerekmiyorsa ve requests olağandan fazla ise işlemleri kuyruklamak gelen tüm request’leri işleyebileceğiniz anlamına gelir. Bir yandan gelen request’leri kuyruğa atarsınız diğer bir yandan ise sıra ile işlersiniz. Veriyi işlemek için yazdığınız kodu (Worker) çoklu şekilde çalıştırarak veri işleme hızınızı da arrtırabilirsiniz.

Queue işlemi basitçe şöyle çalışıyor. bir Job oluşturuyorsunuz. yapılacak işlemleri redis queue atıyorsunuz. artisan work komutu ile queue ve Job‘u belirterek verileri sırası ile işlemeye başlıyorsunuz.

İşe ilk olarak .env dosyasında queue için ne kullanılacağını belirterek başlayalım. Bu kısım oldukça önemli ve redis kullanılması öneriliyor.

QUEUE_CONNECTION=redis

Laravel tarafından redis‘in kullanılabilmesi için predis‘i composer ile kurun.

composer require predis/predis

Şimdi ise işlemleri yapacak olan Job‘un oluşturun.

php artisan make:job Test

Yukarıdaki komut app/Jobs/Test.php dosyasını oluşturur. handle() fonksiyonu worker tarafından çalıştırılacak kod blogunun yazıldığı fonksiyondur. Örnek olması açışından storage/app/ içinde random txt dosyası oluşturan ufak bir kod yazarak devam edelim.

public function handle()
{
    Storage::put(Str::random().'.txt', 'job test');
}

Queue‘ye iş atamamız gerekiyor ben bunun için HomeController@home action’ını kullanacağım.

        public function home()
        {
            $job   = new Test();
            $queue = 'fatih';

            dispatch($job)->onQueue($queue);
        }

Eğer işleme gecikme koymak delay() fonksiyonunu kullanabilirsiniz.

        public function home()
        {
            $job   = new Test();
            $queue = 'fatih';

            dispatch($job)
                ->onQueue($queue)
                ->delay(now()->addMinutes(10));
        }

HomeController@home action’ını çalıştırdığınızda. Redis‘e basit bir iş eklemiş olacaksınız. Eğer Redis-cli içinde key * kodunu çalıştırırsanız

1) "laravel_database_queues:fatih:notify"
2) "laravel_database_queues:fatih"

Şeklinde bir çıktı almanız gerek. Queue‘ye eklediğiniz bu bu işi işlemek içinse artisan work ile worker çalıştırmak gerekiyor.

php artisan queue:work

Yukarıda ki kod tüm worker‘ları çalıştırır. Oysa biz worker‘ları kuyruk kuyruk ayırarak çalıştırmayı tercih ederiz. Bu şekilde hem yönetmesi daha kolay olur hemde bir worker‘da olan sorun diğerlerini etkilemez. Bunun için aşağıdaki gibi queue ismi vererek çalıştırmakta fayda var.

php artisan queue:work --queue=fatih

İşlenecek verilerin birisinde sorun olursa worker‘ı loop’a girmekten kurtarmak için tries yani deneme limiti vermemiz gerekiyor.

php artisan queue:work --queue=fatih --tries=3

Artık storage/app/ içinde üretilen .txt dosyasını görebilirsiniz. Buraya kadar her şey tamam ama Queue iş atarken iş için data göndermek de gerekecektir. Onun için aslında Php class’a parametre göndereceğiz. Yani job classının __construct() fonksiyonunu kullanacağız.

class Test implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;


    public $data = null;


    public function __construct($data)
    {
        $this->data = $data;
    }


    public function handle()
    {
        Storage::put(Str::random().'.txt', $this->data);
    }
}

app/Jobs/Test.php dosyasının içeriğini yukarıdaki gibi hazırladıktan sonra. dispatch ettiğimiz HomeController@home action’dan parametre gönderebiliriz.

        public function home()
        {
            $job   = new Test('data');
            $queue = 'fatih';

            dispatch($job)->onQueue($queue);
        }

Artık üretilen .txt dosyası içerisinde data yazacaktır.

Notlar

  • Job içerisinde yapılan değişiklikler worker tarafından algılanmaz. Bunun için çalışan workerları durdurup yeniden çalıştırmak gerekir.
  • Worker’ları yönetmek için Supervisor kullanmanızı tavsiye ederim.

Yorum Ekle

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gerçek kişi doğrulaması

3 + 4 =