Cấu hình Laravel Queue trên môi trường production

160

Chào các bạn,

Trên môi trường local, chúng ta khởi động queue bằng cách chạy command:

php artisan queue:work

Nhưng trên môi trường production thì không ai rảnh mà lúc nào cũng bật một terminal để chạy command trên cả, mà sẽ có cách khác, và trong bài viết ngắn gọn này mình sẽ chỉ bạn điều đó.

I. Supervisor

1.1 Cấu hình supervisor để chạy queue

Supervisor là một chương trình giám sát tiến trình trên hệ điều hành Linux, mặt khác Laravel thường được deploy trên các server Linux, vì thế mình sẽ sử dụng Supervisor để giám sát việc chạy queue Laravel.

Hiểu nôm na, Supervisor sẽ giúp chúng ta chạy ngầm cái command
php artisan queue:work ngay cả khi tắt terminal.

Để sử dụng supervisor làm “giám sát viên” cho queue, ta thực hiện các bước sau:

Bước 1: Cài đặt Supervisor trên Linux (ở đây mình sử dụng Ubuntu)

sudo apt-get install supervisor

Bước 2: Cấu hình supervisor

Mỗi một tiến trình do Supervisor giám sát sẽ được cấu hình ở một file dạng *.conf nằm trong thư mục /etc/supervisor/conf.d. Nên mình sẽ tạo ra một file có tên là laravel-workder.conf để cấu hình tiến trình chạy queue của Laravel.

sudo vim /etc/supervisor/conf.d/laravel-workder.conf

Nội dung của file laravel-workder.conf như sau:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/your/project/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true

# user thực hiện command 'php artisan queue:work'
# nhớ thay bằng user có quyền thực hiện command trên nhé
user=forge

numprocs=8
redirect_stderr=true

# Các vấn đề sẽ được log vào đây
stdout_logfile=/path/to/your/project/worker.log

Nhớ thay các đoạn bôi đỏ thành thông tin phù hợp với dự án của bạn, sau đó lưu file lại.

Bước 3: Khởi động queue

Mỗi khi thay đổi các thông tin cấu hình Supervisor, bạn cần phải khởi động lại Supervisor bằng các command sau:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

Bạn cũng có thể tìm hiểu thêm thông tin về Supervisor qua tài liệu chính thức.

Vậy là xong, Supervisor đã thay bạn chạy command php artisan queue:work, và queue bây giờ đã sẵn sàng hoạt động.

2.2 Một số command hay sử dụng của supervisor

Tặng bạn một số thao tác phổ biến với Supervisor:

CommandMô tả
sudo service supervisor restartKhởi động lại toàn bộ supervisor
sudo supervisorctl stop laravel-worker:*Dừng worker laravel-worker:*
sudo supervisorctl start laravel-worker:*Khởi động worker laravel-worker:*
sudo supervisorctl restart laravel-worker:*Khởi động lại worker laravel-worker:*

2.3 Một số vấn đề thường gặp với supervisor

Khi sử dụng Supervisor để chạy queue Laravel, thường có một số vấn đề (lỗi) kèm hướng khắc phục như sau:

Queue không chạy

Có rất nhiều nguyên nhân dẫn đến queue không chạy, vì thế hãy đọc file log worker.log để biết thêm thông tin (cũng nên kết hợp đọc cả file storage/logs/laravel.log nữa).

Vẫn chạy “job cũ

Code trong job được update, thế nhưng nó không chạy theo code mới, mà lại chạy theo code cũ. Gặp trường hợp này, hãy thử khởi động lại supervisor:

sudo service supervisor restart

II. Queue Driver

Queue đã tự động chạy với Supervisor, giờ chúng ta tìm hiểu kỹ hơn về các queue driver có trong Laravel.

Queue driver là các “loại queue” có trong Laravel, chúng đều có mục đích là giúp queue có thể hoạt động, nhưng mỗi loại queue lại có các tính chất (hiệu năng, cách cài đặt, cách chạy) khác nhau, và tùy từng dự án mà chúng ta sẽ sử dụng các loại queue khác nhau.

Từ Laravel 6.x, Queue driver được gọi là Queue connection, chỉ là đổi cách gọi tên, còn chúng vẫn là một.

2.1 Sync

Queue sync là queue mà … dùng như không dùng. Các job khi đưa vào queue sẽ được thực hiện ngay lập tức. Cũng có thể hiểu, khi cấu hình queue driver là sync tức là bạn đã tắt queue trong Laravel.

Queue sync chỉ nên sử dụng để dev trên local, không nên để trên production.

Cách cài đặt

Mở file .env, tìm dòng QUEUE_DRIVER=XXX, đổi thành QUEUE_DRIVER=sync.

Lưu ý: với Laravel 6.x trở nên thì QUEUE_DRIVER đổi thành QUEUE_CONNECTION.

2.2 Database

Với queue database, các job sẽ được lưu vào trong database để chạy dần dần. Vì lưu trữ job trong database, nên chúng ta sẽ cần tạo một vài table mới để lưu trữ, nhưng không sao, laravel đã tạo sẵn cho bạn command để cài đặt rồi.

Cách cài đặt

Chạy command sau để tạo bảng lưu trữ các job:

php artisan queue:table
php artisan migrate

Cấu hình .env

QUEUE_DRIVER=database

Queue database cũng phù hợp để sử dụng trên production.

2.3 Redis

Redis là một dạng database lưu trữ trên RAM, đặc điểm của nó là tốc độ đọc – ghi rất nhanh, rất phù hợp để làm nơi lưu trữ các job của queue. Để sử dụng queue driver là redis, trước tiên bạn cần cấu hình thông tin kết nối tới redis ở config/database.php trước đã:

// config/database.php

// ...
'redis' => [
    'client' => 'predis',
    
    // Hãy đảm bảo các thông tin kết nối tới redis là chính xác
    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

],

Bạn có thể tìm hiểu thêm về cách cài đặt và cấu hình redis database theo tài liệu của Laravel.

Cách cài đặt

Về cơ bản, bạn chỉ cần cấu hình thông tin kết nối tớ redis ở file config/database.php là đủ, nhưng bạn cũng nên xem qua file config/queue.php

// config/queue.php

// ...
'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => '{default}',
    'retry_after' => 90,
],

Cấu hình lại thông tin trong .env

QUEUE_DRIVER=redis

Redis rất phù hợp để làm driver cho queue trên môi trường production của Laravel.

III. Tổng kết

Một bài viết ngắn gọn ghi chú lại các kiến thức và kinh nghiệm cấu hình Queue Laravel trên production, hy vọng sẽ giúp ích cho nhiều bạn.

Xin chào, hẹn gặp lại.