Hàng đợi hay Queue được sử dụng để hỗ trợ giảm tải cho server thực thi cùng lúc rất nhiều các yêu cầu hay công việc mất thời gian xử lý từ phía người dùng. Nó là 1 danh sách các công việc được quản lý theo thứ tự và cho phép trì hoãn tới 1 khoảng thời gian nào đó mới thực thi. Trong Yii2 Framework có cung cấp 1 phần mở rộng là yii2-queue

 

Cài đặt 

Để cài đặt Yii2 Queue các đồng dev chạy lệnh sau trong command:

php composer.phar require --prefer-dist yiisoft/yii2-queue

//hoặc

composer require --prefer-dist yiisoft/yii2-queue

Queue Drivers

Yii2 Queue là một extension thực thi các công việc một cách bất đồng bộ thông qua hàng đợi. Nó hỗ trợ các driver như:

- Syncronous: Chạy đồng bộ các công việc ngay lập tức khi các queue được khởi động và được khuyên dùng khi đang phát triển hoặc gỡ lỗi ứng dụng.

- File: Thông tin queue lưu lại dưới dạng file.

- Db: Thông tin queue lưu lại trong database.

- Một số driver service khác: RedisRabbitMQBeanstalkGearman.

Cấu hình Queue trong Yii

Ở bài viết này tại hạ sẽ chỉ giới thiệu cấu hình trên các driver cơ bản như: Sync, File, Db. Còn các driver còn lại tại hạ sẽ viết riêng một bài viết khác về cách cài đặt và sử dụng 

Khi sử dụng Queue đồng nghĩa các đồng dev sẽ tạo ra các Job để thêm các task vào Queue, ở đây tại hạ tạo ra 1 thư mục jobs có file job là TestQueue như sau:

yii queue

Nhớ là khai báo alias @jobs trong common/config/boostrap.php nhé

<?php
Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('@jobs', dirname(dirname(__DIR__)) . '/jobs');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');

Trong SiteController tại hạ chạy queue ở actionQueue như sau

<?php
namespace frontend\controllers;

use Yii;
use yii\base\InvalidArgumentException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
use jobs\TestQueue;

/**
 * Site controller
 */
class SiteController extends Controller
{
    //............
    public function actionQueue()
    {
        Yii::$app->queue->push(new TestQueue('abc'));
    }
}

Trong actionQueue này tại hạ sẽ push vào queue 1 Job là job TestQueue truyền vào tham số là biến $name phía bên khởi tạo TestQueue sẽ nhận và đẩy ra log server. Ngoài cách này chỉ để test Queue chạy hay không, các đồng dev có thể tạo ra các job về gửi mail hoặc gửi tin nhắn .... để đưa vào queue giúp giảm tải thời gian xử lý cho server

queue yii

Syncronous 

Để cấu hình với driver Sync các đồng dev sửa lại file common/config/main.php như sau:

return [
    'components' => [
        'queue' => [
            'class' => \yii\queue\sync\Queue::class,
            'handle' => true, // if tasks should be executed immediately
        ],
    ],
];

Với driver là Sync thì tất cả các task được đưa vào queue sẽ được thực thi ngay lập tức

- FIle

Để cấu hình với driver File các đồng dev sửa lại file common/config/main.php như sau:

return [
   'components' => [
        'queue' => [
            'class' => \yii\queue\file\Queue::class,
            'path' => 'console/runtime/queue',
        ],
    ],
   'bootstrap' => ['queue'],
];

Với driver là File thì khi thực thi các task queue sẽ lưu dưới dạng file các job theo path được set, ở đây tại hạ set đường dẫn là thư mục console/runtime/queue trong console để phục vụ việc chạy command line queue

queue yii2

Sau khi chạy site/queue để push job vào queue thì các file job sẽ được lưu lại trong thư mục queue như ảnh trên.

- Db

Để cấu hình với driver Db các đồng dev sửa lại file common/config/main.php như sau:

yii2 queue

Sau đó các đồng dev chạy câu lệnh Sql sau để tạo bảng lưu các queue

CREATE TABLE `queue` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `channel` varchar(255) NOT NULL,
  `job` blob NOT NULL,
  `pushed_at` int(11) NOT NULL,
  `ttr` int(11) NOT NULL,
  `delay` int(11) NOT NULL DEFAULT 0,
  `priority` int(11) unsigned NOT NULL DEFAULT 1024,
  `reserved_at` int(11) DEFAULT NULL,
  `attempt` int(11) DEFAULT NULL,
  `done_at` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `channel` (`channel`),
  KEY `reserved_at` (`reserved_at`),
  KEY `priority` (`priority`)
) ENGINE=InnoDB

Sau đó chạy thử site/queue sẽ thấy có job trong bảng queue

yii queue

 

Để xem thông tin trạng thái queue, các đồng dev chạy lệnh command line sau

php yii queue/info

Kết quả sẽ như sau

yii queue

Ở đây sẽ hiện thị số lượng các job ở mỗi trạng thái là bao nhiêu. Ví dụ như ảnh trên done là đã có 1 job hoàn thành, waiting là các job mới được push vào queue và đang chờ thực thi, delayed là các job bị trì hoãn thời gian, reserved là các job đã được nhận và đang thực thi

Để chạy queue các đồng dev sử dụng lệnh sau

php yii queue/run

hoặc

php yii queue/listen [timeout]

- run sẽ chạy queue và nhận job, thực thi chúng cho đến khi hàng đợi trống rồi kết thúc. Các đồng dev có thể cài lệnh này vào cron để chạy tự động

- listen cũng giống run nhưng nó sẽ luôn luôn chạy nên được khuyên dùng chạy nền sử dụng supervisor hoặc systemd. option timeout chính là thời gian các đồng dev chờ giữa các queue.

Sau khi chạy log sẽ hiển thị kết quả

queue yii

Để xóa tất cả các job trong queue, các đồng dev sử dụng 

php yii queue/clear

Để xóa job cụ thể, các đồng dev xóa theo option [id] là id của queue job

php yii queue/remove [id]

 

Tổng kết

Bài viết này chỉ mang tính giới thiệu về cách hoạt động của queue trong Yii2, để đi sâu hơn thì queue còn có rất nhiều ứng dụng trong thực tế và nối bật nhất chính là việc gửi mail hàng loạt. Trong bài viết tới, tạ hạ sẽ giới thiệu nốt các driver queue còn lại và demo gửi mail hàng loạt trên các driver queue đó. Bài viết còn nhiều thiếu sót mong các anh em đồng dev thông cảm . Cảm ơn các đồng dev đã đón đọc!.