Message Queue Architecture
How Message Queues Work
Publisher -> Message -> Queue -> Consumer -> Handler
- Publisher sends a message to a queue
- Message is stored in the queue (DB or AMQP)
- Consumer picks up the message
- Handler processes the message
Magento Queue Implementation
Magento uses the Magento\Framework\MessageQueue framework:
- Publisher: sends messages
- Queue: stores messages
- Consumer: receives messages
- Handler: processes messages
Queue Types
| Type | Backend | Use Case |
|---|---|---|
| DB queue | MySQL | Development, simple setups |
| AMQP queue | RabbitMQ | Production, high throughput |
Basic Configuration
<!-- queue_topology.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/topology.xsd">
<exchange name="magento-exchange" type="topic">
<binding id="vendor_product_sync"
topic="vendor.product.sync"
destinationType="queue"
destination="vendor_product_sync_queue"/>
</exchange>
</config>
Queue Configuration Files
queue_topology.xml
Defines exchanges and bindings:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/topology.xsd">
<exchange name="magento-exchange" type="topic">
<binding id="sync_binding"
topic="vendor.product.sync"
destinationType="queue"
destination="product_sync_queue"/>
</exchange>
</config>
queue_publisher.xml
Configures message publishers:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/publisher.xsd">
<publisher id="db" queue="product_sync_queue"/>
</config>
queue_consumer.xml
Configures message consumers:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd">
<consumer name="product_sync_consumer"
queue="product_sync_queue"
handler="Vendor\Module\Model\MessageHandler::process"
maxMessages="1000"
maxIdleTime="0"
sleep="0"/>
</config>
queue_consumer.xml Options
| Option | Description |
|---|---|
| name | Consumer identifier |
| queue | Queue to consume from |
| handler | PHP class/method to process messages |
| maxMessages | Max messages per batch |
| maxIdleTime | Seconds before consumer stops |
| sleep | Seconds between batches |
Publishing Messages
Basic Publisher
namespace Vendor\Module\Service;
use Magento\Framework\MessageQueue\PublisherInterface;
class ProductPublisher
{
public function __construct(
private PublisherInterface $publisher
) {}
public function publish(int $productId): void
{
$this->publisher->publish(
'vendor.product.sync',
json_encode(['product_id' => $productId])
);
}
}
Topic-Based Publishing
// Using topic name directly
$this->publisher->publish(
'vendor.product.sync',
$messageBody // JSON string
);
// Topic maps to exchange via queue_topology.xml
Batch Publishing
public function publishBatch(array $productIds): void
{
foreach ($productIds as $id) {
$this->publisher->publish(
'vendor.product.sync',
json_encode(['product_id' => $id])
);
}
}
Publishing from Observer
namespace Vendor\Module\Observer;
class ProductSaveObserver implements ObserverInterface
{
public function __construct(
private PublisherInterface $publisher
) {}
public function execute(Observer $observer)
{
$product = $observer->getEvent()->getProduct();
$this->publisher->publish(
'vendor.product.sync',
json_encode(['product_id' => $product->getId()])
);
}
}
Queue Consumers
Consumer Handler
namespace Vendor\Module\Model;
use Psr\Log\LoggerInterface;
class MessageHandler
{
public function __construct(
private LoggerInterface $logger
) {}
public function process(string $messageBody): void
{
$data = json_decode($messageBody, true);
$productId = $data['product_id'];
$this->logger->info('Processing product: ' . $productId);
// Process the message
$this->syncProduct($productId);
}
}
Running Consumers
# Run a specific consumer
php bin/magento queue:consumers:start product_sync_consumer
# Run with max messages
php bin/magento queue:consumers:start product_sync_consumer --max-messages=100
# Run all consumers
php bin/magento queue:consumers:start
Consumer in Production
# Supervisor configuration
[program:magento-product-sync]
command=php /var/www/html/bin/magento queue:consumers:start product_sync_consumer --max-messages=1000
autostart=true
autorestart=true
Failure Handling
public function process(string $messageBody): void
{
try {
$data = json_decode($messageBody, true);
$this->syncProduct($data['product_id']);
} catch (\Exception $e) {
$this->logger->error('Message processing failed: ' . $e->getMessage());
throw $e; // Re-throw to retry
}
}
Practice Problems
Messages are piling up in the queue. Consumers are not keeping up. Design a scaling strategy.
Quiz
1. What file defines the exchange and queue bindings?
2. How do you start a queue consumer?
3. What should a consumer handler return on failure?
4. What are the two queue backend types in Magento?
Flashcards
Question
What is the message queue flow?
Click to reveal answer
Answer
Publisher -> Message -> Queue -> Consumer -> Handler
Question
Which file defines queue bindings?
Click to reveal answer
Answer
queue_topology.xml
Question
How to start a consumer?
Click to reveal answer
Answer
php bin/magento queue:consumers:start consumer_name
Question
What happens when a handler throws an exception?
Click to reveal answer
Answer
Message is retried or moved to dead letter queue
Question
Which backends support message queues?
Click to reveal answer
Answer
Database (MySQL) and AMQP (RabbitMQ)
Revision Notes
Key Takeaways
- 1. Message queues enable async processing: Publisher -> Queue -> Consumer
- 2. queue_topology.xml defines exchanges and bindings
- 3. queue_consumer.xml configures consumers with handlers
- 4. queue_publisher.xml configures publishers
- 5. Run consumers with php bin/magento queue:consumers:start
- 6. Throw exceptions in handlers to trigger retry logic
Interview Tips
- • Explain the message queue architecture and components
- • Describe when to use async processing over sync
- • Discuss queue backend choices (DB vs AMQP)
- • Know how to configure and run consumers
Cheat Sheet
Message Queues Cheat Sheet
Files:
- queue_topology.xml: exchanges, bindings
- queue_consumer.xml: consumers, handlers
- queue_publisher.xml: publishers
Publish:
$this->publisher->publish('topic.name', json_encode($data));
Consumer:php bin/magento queue:consumers:start consumer_name
Handler:
public function process(string $message): void {
// Process or throw to retry
}
Backends: DB (dev), AMQP/RabbitMQ (prod)