RabbitMQ的消息有效期(TTL)和隊列有效期(expires)

消息有效期

我們有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');

 

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