RabbitMQ死信隊列原理並實現延遲隊列

死信隊列

死信交換機(Dead-Letter-Exchange),當消息在一個隊列中變成死信之後,它能被髮送到另一個交換機中,這個交換機就是DLX,綁定DLX的隊列就稱之爲死信隊列

消息變成死信一般是由於下面三種情況:

  • 消息被拒絕(Basic.Reject或Basic.Nack),並在調用時設置requeue參數爲false
  • 消息過期
  • 隊列達到最大長度

通過在channel.queueDeclare方法中設置x-dead-letter-exchange參數來爲這個隊列添加DLX

延遲隊列

定義2個隊列,第一個隊列通過設置消息或隊列的有效期,使消息到期後變爲死信進入到第二個隊列中,而我們只消費第二個隊列,則可實現延遲隊列,下面是用php-amqplib實現的一分鐘的延遲隊列

<?php
require_once __DIR__.'/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

$connection = new AMQPStreamConnection('127.0.0.1', 5672, 'why', 'why');
$channel = $connection->channel();

//測試死信的上游交換機
$channel->exchange_declare('dlxBeforeExchange', 'direct',
    false, true, false, false, false, []);
//死信的交換機
$channel->exchange_declare('dlxExchange', 'direct',
    false, true, false, false, false, []);

//測試死信隊列的上游隊列
$dlx_table = new \PhpAmqpLib\Wire\AMQPTable();
$dlx_table->set('x-dead-letter-exchange', 'dlxExchange' );
$dlx_table->set('x-dead-letter-routing-key', 'dlxKey' );
$channel->queue_declare('dlxBeforeQueue',
    false, true, false, false, false, $dlx_table);
$channel->queue_bind('dlxBeforeQueue', 'dlxBeforeExchange', 'dlxBeforeKey');
//死信隊列
$channel->queue_declare('dlxQueue',
    false, true, false, false, false);
$channel->queue_bind('dlxQueue', 'dlxExchange', 'dlxKey');


$head = array_merge(array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT), ['expiration' => '60000']);
$msg = new AMQPMessage('hello why', $head);
$res = $channel->basic_publish($msg, 'dlxBeforeExchange', 'dlxBeforeKey');

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章