消息有效期
我們有2種方式設置消息的有效期:
- 一種是通過隊列屬性x-message-ttl設置,投遞到該隊列中的所有消息都有相同的過期時間
- 另一種是通過消息屬性expiration設置消息本身的有效期
如果兩種同時使用,會以兩者之間較小的那個數值爲準,單位都爲毫秒
兩種設置有效期的刪除策略是不同的:
- 通過隊列設置的,一旦消息過期,就會從隊列中抹去,因爲過期的消息肯定在隊列頭部,RabbitMQ只需要定期處理頭部過期消息即可。
- 而單獨設置有效期的,如果要刪除則需要遍歷整個隊列,所以採取消費時判定是否過期處理刪除
下面是一個用php-amqplib實現的設置有效期的代碼(注意消息的有效期值爲字符串,類型可參考AMQPMessage的$propertyDefinitions屬性):
<?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('normalExchange', 'direct',
false, true, false, false, false);
$m_table = new \PhpAmqpLib\Wire\AMQPTable();
$m_table->set('x-message-ttl', 60000 );
$channel->queue_declare('normalQueue',
false, true, false, false, false, $m_table);
$channel->queue_bind('normalQueue', 'normalExchange', 'normalKey');
$head = array_merge(array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT), ['expiration' => '6000']);
$msg = new AMQPMessage('hello why', $head);
$res = $channel->basic_publish($msg, 'normalExchange', 'normalKey');
上面這段代碼最終消息的有效期爲6秒。
隊列有效期
通過channel.queueDeclare方法中到x-expires參數是可以控制隊列在指定時間未被使用過後刪除,未被使用包括以下三點:
- 沒有任何消費者
- 未被重新聲明過期時間
- 未調用過Basic.Get命令
<?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('normalExchange', 'direct',
false, true, false, false, false);
$m_table = new \PhpAmqpLib\Wire\AMQPTable();
$m_table->set('x-expires', 60000 );
$channel->queue_declare('normalQueue',
false, true, false, false, false, $m_table);
$channel->queue_bind('normalQueue', 'normalExchange', 'normalKey');