Hiểu đơn giản thì cơ chế của message queue sẽ thực hiện thông qua cron job. Đầu tiên chúng ta phải gửi message đến queue có thể kèm theo tham số và queue sẽ thực hiện công việc của nó. Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu về cách tạo một queue trong Magento 2.
Để tạo một queue trong Magento 2, đầu tiên chúng ta cần phải tạo 4 file .xml trong thư mục <vendor>/<module>/etc/:
communication.xml
ViMagento/HelloWorld/etc/communication.xml
1 2 3 4 5 6 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Communication/etc/communication.xsd"> <topic name="vimagento.queue.topic" request="string"> <handler name="vimagentoExample" type="ViMagento\HelloWorld\Model\Queue\Consumer" method="process" /> </topic> </config> |
Topic element
PARAMETER | MÔ TẢ |
---|---|
name | Một chuỗi duy nhất định danh cho topic name. Topic name nên là các chuỗi nhỏ được phân cách nhau bởi dấu chấm. |
request | Kiểu dữ liệu của topic name (string, array). |
response | Xác định kiểu dữ liệu của phản hồi. Tham số này là bắt buộc nếu bạn định nghĩa một topic đồng bộ. Nếu không hãy bỏ qua nó. |
schema | Interface mô tả cấu trúc của message queue. Định dạng phải là <module>\Api\<ServiceName>::<methodName> . |
Handler element
Đây là phần xác định class sẽ xử lý logic.
PARAMETER | MÔ TẢ |
---|---|
name | Tên định danh cho handler và là duy nhất. |
type | Class hoặc interface sẽ xử lý logic cho topic. |
method | Phương thức sẽ thực thi khi queue chạy. |
disabled | Xác định xem handler có bị vô hiệu hóa hay không. Mặc định là false. |
Sau đó các bạn tạo class handler đã khai báo ở trên.
ViMagento\HelloWorld\Model\Queue\Consumer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace ViMagento\HelloWorld\Model\Queue; class Consumer { /** * @param $data */ public function process($data) { // $data là tham số được truyền vào khi bạn gửi một message vào queue // Your logic } } |
queue_consumer.xml
ViMagento/HelloWorld/etc/queue_consumer
.xml có thể chứa nhiều node consumer.
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd"> <consumer name="vimagento.queue.topic" queue="vimagento.queue.topic" connection="db" maxMessages="5000" consumerInstance="Magento\Framework\MessageQueue\Consumer" handler="ViMagento\HelloWorld\Model\Queue\Consumer::process"/> </config> |
ATTRIBUTE | MÔT TẢ |
---|---|
name (required) | Tên của consumer. |
queue (required) | Xác định queue name để gửi message. |
handler | Xác định class và method sẽ thực thi message. Có định dạng <Vendor>\Module\<ServiceName>::<methodName> . |
consumerInstance | Tên class name Magento sẽ xử lý message. |
connection | For AMQP connections, the connection name must match the connection attribute in the queue_topology.xml file. Otherwise, the connection name must be db . |
maxMessages | Xác định số lượng message tối đa. |
maxIdleTime | Xác định thời gian đợi tối đa (tính bằng giây) để thực thi đỗi với một queue mới. Mặc định: null
|
queue_topology.xml
ViMagento/HelloWorld/etc/
.xmlqueue_topology
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/topology.xsd"> <exchange name="magento-db" type="topic" connection="db"> <binding id="processViMagentoExampleToQueueBinding" topic="vimagento.queue.topic" destinationType="queue" destination="vimagento.queue.topic"/> </exchange> </config> |
queue_publisher.xml
1 2 3 4 5 6 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/publisher.xsd"> <publisher topic="vimagento.queue.topic"> <connection name="db" exchange="magento-db" /> </publisher> </config> |
Sau đó các bạn chạy câu lệnh php bin/magento setup:upgrade để thêm queue đã tạo vào hệ thống. Nếu thành công các bạn kiểm tra trong bảng queue sẽ thấy topic name vừa tạo. Ngược lại nếu không có bạn cần kiểm tra lại 4 file đã tạo.

Thêm message vào queue
Một ví dụ khi bạn generate coupon trong cart price rule, bạn sẽ thấy chúng sẽ không generate ngay mà chúng sẽ thêm request của chúng ta vào queue và cron sẽ chạy chúng.

Tương tự như trên chúng ta cũng sẽ tạo một Controller để thực hiện thêm message vào queue.
ViMagento/HelloWorld/Controller/Adminhtml/Index/Index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?php namespace ViMagento\HelloWorld\Controller\Adminhtml\Index; use Magento\Backend\App\Action; /** * Class Index * @package ViMagento\HelloWorld\Controller\Adminhtml\Index */ class Index extends \Magento\Backend\App\Action { const ADMIN_RESOURCE = 'ViMagento_HelloWorld::add_queue'; const TOPIC_NAME = 'vimagento.queue.topic'; /** * @var \Magento\Framework\MessageQueue\PublisherInterface */ protected $publisher; /** * @var \Magento\Framework\Serialize\Serializer\Json */ protected $json; /** * Index constructor. * @param \Magento\Framework\MessageQueue\PublisherInterface $publisher * @param \Magento\Framework\Serialize\Serializer\Json $json * @param Action\Context $context */ public function __construct( \Magento\Framework\MessageQueue\PublisherInterface $publisher, \Magento\Framework\Serialize\Serializer\Json $json, Action\Context $context ) { $this->publisher = $publisher; $this->json = $json; parent::__construct($context); } public function execute() { try { // Dữ liệu mà bạn muốn thêm vào queue cũng là tham số ở hàm thực thi process() $data = [1, 2, 3]; // Thêm vào queue, vì tôi đã khai báo type là string ở file communication.xml // nên phải chuyển data sang kiểu string $this->publisher->publish(self::TOPIC_NAME, $this->json->serialize($data)); $this->messageManager->addSuccessMessage(__('Message is added to queue, wait to get your coupons soon')); } catch (\Exception $exception) { $this->messageManager->addErrorMessage(__($exception)); } return $this->_redirect('*/*/redirect'); } } |
Sau đó tôi chạy controller thành công và kiểm tra bảng queue_message (chứa các message trong hàng đợi) sẽ có một record tương ứng tôi vừa thêm vào.

Message queue Status
Sau khi đã thêm message vào hàng đợi, cron job sẽ thực thi method process($data) mà chúng ta đã tạo ở đầu bài viết, với $data là body trong bảng queue_message. Để xem message của bạn đã được thực thi thành công hay chưa bạn có thể xem ở bảng queue_message_status.

Bạn có thể xem tất cả status của message queue tại: Magento\MysqlMq\Model\QueueManagement

Thực thi message
Message sẽ được thực thi bởi cron job được cấu hình trong Magento/MessageQueue/etc/crontab.xml

Bạn cũng có thể thực thi message queue với CLI bằng câu lệnh:
1 |
php bin/magento queue:consumers:start [topic_name] |
Ví dụ: php bin/magento queue:consumers:start vimagento.queue.topic
Xem thêm tại devdocs của magento: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/message-queues/config-mq.html
Xem thêm: