Laravel Queue ve SuperVisor ile Asenkron İşlemler

Laravel, PHP tabanlı popüler web uygulama geliştirme frameworküdür. Laravel Queue, Laravel'in sağladığı bir bileşendir ve asenkron görevleri yönetmek için kullanılır. Amacı uygulamanın hızla yanıt vermesini sağlamaktır. Bunu yapabilmek için uzun sürecek işlemleri ve ya arka planda yürütülmesi gereken süreçleri bir iş listesine alarak daha sonra işlemeyi sağlar.

Laravel Queue, Redis, Amazon SQS ve ilişkisel bir veritabanı gibi farklı kuyruk sürücüleri ile çalışabilir. Kuyruk sürücüsü, asenkron görevleri depolamak ve almak için kullanılan bir hizmettir. Bu görevler, veritabanında veya bir kuyruk sistemi sunucusunda saklanır ve ardından belirli bir sırayla işlenir.

Laravel Queue, programınızı daha ölçeklenebilir hale getirir ve kullanıcı deneyimini iyileştirmek için önemli bir rol oynar. Ayrıca, sıradaki görevleri izleme, yeniden deneme, gecikme, önceliklendirme gibi farklı kuyruk yönetim işlevlerini de sağlar.

Laravel Queue Kullanım Alanları Nelerdir?

Laravel Queue, çeşitli kullanım alanlarına sahiptir ve birçok senaryoda faydalı olabilir. Yaygın kullanım alanlarından bazıları şunlardır;

E-posta gönderme: Laravel Queue, e-posta gönderme işlemlerini sıraya almak için kullanılabilir. Örneğin, kullanıcılara otomatik olarak e-posta göndermek için bir kuyruk oluşturabilirsiniz. Bu şekilde, e-postalar hemen gönderilmek yerine, bir kuyruğa eklenir ve Laravel Queue, sıradaki görevleri işleyerek e-postaları gönderir.

Veritabanı işlemleri: Laravel Queue, uzun süren veritabanı işlemlerini veya yoğun kaynak gerektiren işlemleri sıraya almak için kullanılabilir. Bu, büyük veri kümelerini işlerken performansı artırabilir ve kullanıcı deneyimini iyileştirebilir.

Resim işleme: Web uygulamalarında resim işleme işlemleri sıklıkla kullanılır. Örneğin, kullanıcıların yüklediği resimleri yeniden boyutlandırmak, optimize etmek veya farklı formatlara dönüştürmek gibi işlemler zaman alabilir. Laravel Queue kullanarak, bu tür resim işleme görevlerini arkaplanda sıraya alabilir ve web uygulamasının hızlı yanıt vermesini sağlayabilirsiniz.

Dosya işlemleri: Dosyaların indirilmesi veya yüklenmesi gibi dosya işlemleri, bazen zaman alıcı olabilir. Laravel Queue kullanarak, bu tür işlemleri arkaplanda sıraya alabilir ve web uygulamasının performansını artırabilirsiniz.

Entegrasyonlar: Laravel Queue, diğer sistemlerle entegrasyon için kullanılabilir. Örneğin, üçüncü taraf API çağrıları veya uzak hizmetlerle iletişim, Laravel Queue kullanılarak asenkron bir şekilde yönetilebilir. Bu, web uygulamanızın daha hızlı ve daha verimli çalışmasına yardımcı olabilir.

Bunlar sadece Laravel Queue'in kullanım alanlarına örneklerdir ve gerçek kullanım senaryoları projenizin ihtiyaçlarına bağlı olarak değişebilir. Laravel Queue, uzun süren veya yoğun işlemleri asenkron olarak yönetmek ve web uygulamanızın performansını artırmak için güçlü bir araçtır.

Laravel Queue Nasıl Kullanılır?

Yapılandırma (Configuration)

Laravel Queue kullanmaya başlamadan önce yapılandırma işlemlerini tamamlamanız gerekir. Bu yapılandırma işlemi için .env ve config/queue.php dosyasında ilgili düzenlemeleri yapabilirsiniz.

.env dosyasında QUEUE_CONNECTION değerinin işlemlerin depolanıp, okunacağı sürücüyü belirtmeniz gerekiyor. Bu varsayılan olarak "sync"dir. Yani işlemler kuyruğa alınmadan doğrudan yürütülür. Aynı şekilde kullanacağınız bu kuyruk sürücünün bağlantı bilgileri gibi bilgileri config/queue.php dosyasında işaret edilen ortam değişkenlerinden de (.env) doğru tanımlamanız gerekiyor.

Gereksinimlerin Hazırlanması

Yapılandırma işlemlerini yaptığımıza göre artık Queue için ihtiyacımız olan bazı şeyleri hazırlamamız gerekiyor.

Not : İçeriğin bu kısmı kuyruk sürücüsü olarak veritabanı kullanılacağı düşünülerek hazırlanmıştır. Redis veya Amazon SQS gibi farklı bir kuyruk sürücüsü kullanacaksanız gereksinimlerin hazırlanması farklılık gösterebilir.

Başlamadan önce veritabanımızda işlerin depolanacağı tabloyu oluşturmamız gerekiyor. Bu işlemi gerçekleştirmek için aşağıdaki artisan komutunu çalıştırabilirsiniz.

php artisan queue:table
php artisan migrate

Yukarıdaki ilk komut jobs tablosu için bir migration oluşturacak ve ikinci komut ise bu migrationları uygulayacaktır. Böylece veritabanında jobs isimli bir tablomuz var olacak.

İşin Tanımlanması ve Kuyruğa Eklenmesi

Kuyruğa eklenecek işler için işleri yürütecek yapıyı oluşturmamız gerekiyor. Oluşturduğumuz bu yapı (sınıf), kuyrukta sıradan alınan işleri işleme işini bizim için yapacaktır.

Ben örnek olması açısından arka planda mail gönderimi yapacak bir iş oluşturacağım ve SendMailJob adını vereceğim. Siz bu isimlendirme ve işlemi istediğiniz gibi yapabilirsiniz.

php artisan make:job SendMailJob

Bu komut app/Jobs/SendMailJob.php dosyasını bizim için oluşturacaktır. Dosya içeriği ise şuna benzer olacaktır;

<?php
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

public function __construct()
{
}

public function handle()
{
}

}

Burada __construct metodu bizim bu iş için kullanacağımız parametreleri dışarıdan almamızı sağlayacak metottur. Eğer bu iş dışarıdan bir parametre alarak çalışacaksa, Laravel bizim için işin yürütülme zamanında bu parametreleri bu metoda birer argüman olarak gönderir. Bu örnekte isim ve mail olmak üzere iki parametre kullanıcaz.
handle metodu ise işlemin yapılacağı metottur.

<?php
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

private string $name;
private string $mail;

public function __construct($name, $mail)
{
$this->name = $name;
$this->mail = $mail;
}

public function handle()
{
$subject = 'Merhaba ' . $this->name;
$msg = 'Sitemize üye olduğunuz için teşekkür ederiz!';
if (!mail($this->mail, $subject, $msg)) {
throw new \Exception("Mail gönderilemedi.");
}
}

}

Şimdi oluşturduğumuz bu iş için kuyrağa yeni bir iş ekleyelim. Bunun için aşağıdaki PHP kodunu kullanabilirsiniz;

\App\Jobs\SendMailJob::dispatch('Muhammet', 'info@muhammetsafak.com.tr');

Kuyruktaki İşlemlerin Yürütülmesi

Kuyruğa alınmış işlemlerin yürütülmesi için aşağıdaki artisan komutu yürütülür. Bu komut kuyruk sürücüsündeki iş listesini sürekli olarak dinleyerek yeni bir iş eklendiğinde devreye girerek çalışmaya devam eder.

php artisan queue:work

Kuyruktaki İşlemlerin İsimlendirilmesi

Laravel varsayılan olarak "default" adında bir iş listesi tanımlar ve bu iş listesini dinler. Ancak aynı proje içerisinde birden fazla iş listesi tanımlamak ve bunları farklı zamanlarda çalıştırmak isteyebilirsiniz. Bu işlem için onQueue() metodunu kullanabilirsiniz.

\App\Jobs\SendMailJob::dispatch('Muhammet', 'info@muhammetsafak.com.tr')->onQueue('medium');

Bu durumda işiniz belirttiğiniz isimde farklı bir iş listesine eklenir. "default" dışındaki farklı bir iş listesini yürütmek için kullandığınız artisan komutunu da değiştirmeniz gerekir.

php artisan queue:work --queue=medium

Birden fazla iş listesini işlemek için ise, iş listelerinin adını virgül kullanarak birbirinden ayırmanız yeterlidir.

php artisan queue:work --queue=medium,default

Artık temel seviyede Laravel Queue kullanımını ve temel işleyişi biliyorsunuz. Şimdi sizin yerinize Laravel'den sıradaki işleri işlemesini isteyecek bir araca ihtiyacımız var.

SuperVisor

Supervisor, Unix ve Unix benzeri işletim sistemlerinde arka planda çalışan süreçleri yönetmek için kullanılan bir sistem aracıdır. Supervisor, sistemdeki uygulamaların sürekli olarak çalışmasını sağlamak ve arıza durumlarında otomatik olarak yeniden başlatmak için kullanılır.

Supervisor, genellikle web sunucuları, veritabanı sunucuları, kuyruk işleyicileri gibi sürekli çalışması gereken uygulamaların yönetimi için tercih edilir. Ayrıca, Laravel Queue gibi kuyruk işleme sistemlerinin sürekli olarak çalışmasını sağlamak için de Supervisor kullanılabilir.

Supervisor'un başlıca özellikleri şunlardır:

Sürekli süreç yönetimi: Supervisor, belirtilen süreçleri izler ve sürekli olarak çalışmalarını sağlar. Eğer bir süreç beklenmedik bir şekilde durursa, Supervisor tarafından otomatik olarak yeniden başlatılır.

Yeniden başlatma politikaları: Supervisor, süreçlerin yeniden başlatılma politikalarını yönetir. Örneğin, bir süreç belirli bir hata sayısını aşarsa veya belirli bir süre boyunca çalışmazsa, Supervisor tarafından yeniden başlatılabilir.

Günlük dosyaları ve hata raporlaması: Supervisor, çalışan süreçlerin günlük dosyalarını izler ve hata raporlamasını sağlar. Böylece, süreçlerin durumunu takip edebilir ve hataları belirleyebilirsiniz.

Çoklu süreç grupları: Supervisor, birden fazla süreç grubunu yönetebilir. Bu gruplar, farklı uygulamaları veya süreçleri kategorilere ayırmak ve ayrı ayrı yönetmek için kullanılabilir.

Supervisor, genellikle bir yapılandırma dosyası (supervisord.conf) kullanarak yapılandırılır. Bu dosyada, yönetilecek süreçlerin tanımları, yeniden başlatma politikaları ve diğer özellikler belirtilir. Supervisor, bu yapılandırma dosyasını kullanarak süreçleri başlatır ve yönetir.

Laravel Queue gibi sürekli çalışması gereken uygulamaları Supervisor ile yönetmek, uygulamanın istikrarlı bir şekilde çalışmasını sağlar ve arıza durumlarında otomatik olarak yeniden başlatılmasını sağlar. Supervisor'un sağladığı güçlü yönetim özellikleri, uygulamaların sürekliliğini artırır ve sorunların hızlı bir şekilde tespit edilmesine yardımcı olur.

Supervisor Kurulumu

Supervisor kullanımına ve laravel entegrasyonuna geçmeden önce sunucunuzda supervisor kurulu olmalıdır.

sudo apt-get update
sudo apt-get install supervisor -y

Yukarıdaki komut ile supervisor uygulamasını sunucunuza kurabilirsiniz.

Supervisor Laravel Entegrasyonu

Supervisor kurulumunu tamamladığımıza göre sıra laravel queue ile entegre etmeye geldi. Sunucunuzda terminal üzerinde aşağıdaki komutu yürüterek Supervisor yapılandırma dizinine ulaşın.

cd /etc/supervisor/conf.d/

Şimdi bir yapılandırma dosyası oluşturalım.

sudo nano programAdi.conf

Ve aşağıdaki yapılandırmayı kendinize göre düzenleyerek yapıştırın.

[program:programAdi]
process_name=%(program_name)s_%(process_num)02d
command=php projeYolu/artisan queue:work --queue=default
autostart=true
autorestart=true
user=sistemKullaniciAdi
numprocs=8
redirect_stderr=true
stdout_logfile=projeYolu/storage/logs/worker.log
stopwaitsecs=3600

CTRL+O ile kaydedip ve CTRL+X ile kapatıyoruz.

Ardından supervisor servisinin yaptığımız değişiklikleri algılamasını sağlamak için aşağıdaki komutları çalıştırıyoruz.

sudo supervisorctl reread
sudo supervisorctl update

Ardından supervisor servisini başlatmak için aşağıdaki komutu çalıştırıyoruz.

sudo supervisorctl start programAdi:*

İşlemlerin tümü başarılıysa artık hazırsınız.

Daha ayrıntılı bilgi için;
Supervisor Dökümanına http://supervisord.org/ adresinden, Laravel Queue dökümanına https://laravel.com/docs/10.x/queues adresinden ulaşabilirsiniz.