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');

 

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