死信队列
死信交换机(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');