Chắc hẳn những anh em mới bắt đầu tiếp cận và làm việc với Laravel đều thấy việc gửi 1 email thật đơn giản khi sử cần sử dụng hàm Mail của Laravel đúng không ạ. Mình cũng thế. Khi mới học và làm 1 cài con web cỏ (thực ra là mấy bài tập nho nhỏ của các thầy giao cho 😀 ) nghĩ thật đơn giản, ấn nút gửi là xong. Nhưng khi được thầy hỏi, nếu gửi 1 lúc cho 10 nghìn người hay 10 nghìn người cùng thao tác nút gửi mail đó sẽ ra sao. Chắc server của mình cứ thế load mãi, load mãi và lăn đùng ra mà die mất 😄.
Và từ đó mình đã tìm hiểu Laravel Queue và Supervisor.
Laravel Queue là gì?
Queue là một danh sách những công việc cần làm (job) hàng đợi cần được xử lý theo thứ tự. Ví dụ khi có 1000 người click vào nút gửi mail của mình, tất cả sẽ được xếp theo thứ tự và việc gửi mail sẽ được xử lý lần lượt. Và các job sẽ có thể được lưu vào nhiều nơi khác nhau (database, redis), tùy theo việc bạn cài đặt trong env
. Ví dụ, nếu bạn muốn lưu job vào database:
QUEUE_DRIVER=database
và nhớ đừng quên chạy
php artisan queue:table
php artisan migrate
Tạo job
Đầu tiên bạn cần tạo cho mình 1 job để xử lý công việc của bạn. Ví dụ ở đây mình cần gửi mail reset mật khẩu
php artisan make:job SendEmailResetPassword
Và trong app/Jobs
của mình sẽ có file SendEmailResetPassword.php
như sau:
<?php
namespace App\Jobs;
use App\Mail\ResetPasswordMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
class SendEmailResetPassword implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
private $dataReset;
public function __construct($dataReset)
{
$this->dataReset = $dataReset;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
Mail::to($this->dataReset['email'])->send(new ResetPasswordMail($this->dataReset));
}
}
Tạo template email
Các bạn hãy chạy lệnh sau
php artisan make:mail ResetPasswordMail
Và giờ hãy vào app/Mail
và bạn sẽ thấy file vừa tạo. Hiểu cơ bản thì đây sẽ là file giúp bạn bind data vào trong mail và gửi cho người dùng
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ResetPasswordMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* @return void
*/
private $dataReset;
public function __construct($dataReset)
{
$this->dataReset = $dataReset;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->with($this->dataReset)->view('mail.reset-password');
}
}
Tiếp tợi hãy tạo một file blade nhé. Như ở trên thì mình sẽ tạo file reset-password.blade.php
trong views/mail
Dispatch Job
Và giờ, ở trong Controller bạn hãy disptach job của mình nhé
SendEmailResetPassword::dispatch($dataReset);
Chạy các jobs trong queue
Để chạy các jobs thì các bạn hãy dùng lệnh:
php artisan queue:work --tries=3
--tries=3
sẽ là số lần bạn thực hiện lại job đó nếu bị fail. Còn một vài thông số nữa về thời gian chờ, thời gian nghỉ,.. thì các bạn chịu khó lên docs của Laravel và đọc nhé, ở đây mình sẽ chỉ giới thiệu qua như vậy
Cách chạy queue trên server
Ơ nhưng mà chẳng lẽ lúc nào chúng ta cũng phải chạy queue:work ở trên server ư. Tất nhiên là không rồi, bạn có thể xử dụng supervisor
để giám sát xử lý các queue trên server
Supervisor
Supervisor là một hệ thống client/server được sử dụng để kiểm soát một số những tiến trình cụ thể của hệ điều hành UNIX, cụ thể hơn là các quy trình liên quan tới một dự án hoặc một khách hàng. Ví dụ, bạn có thể sử dụng supervisor để quản lý hàng đợi trong ứng dụng Laravel của bạn
Các thành phần của supervisor bao gồm:
- supervisor: phần máy chủ của hệ thống
- supervisorctl: giao diện dòng lệnh để tương tác với server
- Web server: Một giao diện web đơn giản để trực quan hóa một số chức năng cơ bản của supervisorctl
- XML-RPC Interface: Giống với HTTP server sử dụng bởi web client, XML-RPC Interface có thể được sử dụng để điều khiển các chương trình của supervisor
Để cài đặt bàn hãy dùng câu lệnh
sudo apt-get install supervisor
Check status:
sudo systemctl status supervisor.service
Tương tự để khởi động, tắt, tạm dừng chúng ta lần lượt thay status
bằng enable
, start
, stop
, disable
Các file cấu hình sẽ nằm trong thư mục etc/supervisor/conf.d
. Ở đây bạn hãy tạo file reset-password.conf và cấu hình như sau nhé
[program:reset-password]
process_name=%(program_name)s_%(process_num)02d
command=php duong-dan-toi-folder-project/artisan queue:work --tries=3
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/duong-dan-ban-muon-luu-log/reset-mail.log
Trong đó:
autostart
: thông báo là chương trình sẽ tự động được khởi động khi supervisor được khởi độngautorestart
: nếu chương trình bị tắt vì bất cứ lý do gì, lệnh này sẽ thông báo cho supervisor khởi động lại chương trìnhstderr_logfile
,stdout_logfile
: định nghĩa đường dẫn log đầu ra và log lỗiredirect_stderr
: nếu là true thì stderr sẽ bị redirect để xuất vào file chỉ định ở stdout_logfilenumprocs
: số lượng tiến trình mà Supervisor sẽ chạy. Ví dụ để gửi mail, ta để numprocs=4, nghĩa là 4 tiến trình cùng chạy task gửi mail.- Xem thêm các section value khác tại đây: http://supervisord.org/configuration.html#program-x-section-values
Sau đó lưu lại và chạy các lệnh sau nhé:
$supervisorctl reread
$supervisorctl update
$supervisorctl start reset-password:*
Tìm hiểu thêm chạy supervisor trên docker: https://docs.docker.com/config/containers/multi-service_container/
Tham khảo: https://www.vultr.com/, https://www.digitalocean.com/, https://youtube.com/, https://viblo.asia/
Cảm ơn tất cả mọi người đã đọc.