RabbitMQ 可以對消息和隊列設置過期時間(TTL)
1、設置消息的TTL
目前有兩種方式可以設置消息的TTL
- 第一種方式是通過隊列屬性設置,隊列中所有消息都有相同的過期時間
- 第二種方式是對消息本身進行單獨的設置,每條消息的TTL可以不同
如果兩種方法一起使用,則消息的TTL已較小的數值為准。
1.1、通過設置隊列屬性來控制消息的TTL
在聲明隊列的時候可以通過 x-message-ttl 屬性來控制消息的TTL, 這個參數的單位是毫秒。如果不設置 TTL.則表示此消息不會過期 ;如果將 TTL 設置為 0,則表示除非此時可以直 接將消息投遞到消費者,否則該消息會被立即丟棄。
可以參考以下測試代碼, github地址:https://github.com/SevenParadise/php-examples/blob/master/mq/rabbitmq/ttl/msg_ttl_with_queue.php
<?php require __DIR__ . '/../../../vendor/autoload.php'; use PhpAmqpLib\Wire\AMQPTable; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Connection\AMQPStreamConnection; // todo 換成自己的配置 $connection = new AMQPStreamConnection('192.168.33.1', 5672, 'zhangcs', 'zhangcs', '/'); $channel = $connection->channel(); // 通過隊列屬性設置消息過期時間為10s, 然后在管理頁面查看10s之后消息是否消失 $arguments = new AMQPTable(); $arguments->set("x-message-ttl", 10000); $queueName = 'test_msg_ttl'; $channel->queue_declare($queueName, false, true, false, false, false, $arguments); $message = new AMQPMessage('Hello RabbitMQ'); $channel->basic_publish($message, '', $queueName); $channel->close(); $connection->close();
運行該代碼之后可以在web管理后台中發現增加了 test_msg_ttl 隊列,然后隊列特性中會有 TTL標志,隊列中會有一條消息。10 秒之后該消息會自動刪除。
1.2、通過設置消息的屬性控制消息的TTL
在創建消息的時候可以指定參數 expiration 來控制消息的TTL,單位是毫秒。
可以參考以下測試代碼,github地址:https://github.com/SevenParadise/php-examples/blob/master/mq/rabbitmq/ttl/msg_ttl.php
<?php require __DIR__ . '/../../../vendor/autoload.php'; use PhpAmqpLib\Wire\AMQPTable; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Connection\AMQPStreamConnection; // todo 換成自己的配置 $connection = new AMQPStreamConnection('192.168.33.1', 5672, 'zhangcs', 'zhangcs', '/'); $channel = $connection->channel(); $queueName = 'test_msg_ttl1'; $channel->queue_declare($queueName, false, true, false, false); // 通過消息屬性設置消息過期時間為10s, 然后在管理頁面查看10s之后消息是否消失 $message = new AMQPMessage('Hello RabbitMQ', [ 'expiration' => 10000 ]); $channel->basic_publish($message, '', $queueName); $channel->close(); $connection->close();
運行該代碼之后可以在web管理后台中發現增加了 test_msg_ttl1 隊列,每條消息的過期時間都不同。
1.3、消息過期之后刪除的時機
對於第一種方式通過隊列屬性控制TTL的消息來說,一旦消息過期,則會立馬刪除,這是因為過期的消息肯定是在隊頭,刪除代價很低。
對於第二種方式來說,消息過期之后是不會立馬刪除的,因為每條消息的過期時間不同,如果要刪除過期消息,那必須掃描整個隊列,代價太高,所以消失是否過期是在消息消費的時候判斷的。
2、設置隊列的TTL
在聲明隊列的時候可以通過 x-expires 參數來控制隊列被自動刪除前處於未使用狀態的時間。未使用的意思是隊列上沒有任何的消費者,隊列也沒有被重新聲明,並 且在過期時間段 內也未調用過 Basic.Get 命令。 x-expires 參數以毫秒為單位。
可以參考以下代碼,github地址:https://github.com/SevenParadise/php-examples/blob/master/mq/rabbitmq/ttl/queue_ttl.php
<?php require __DIR__ . '/../../../vendor/autoload.php'; use PhpAmqpLib\Wire\AMQPTable; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Connection\AMQPStreamConnection; // todo 換成自己的配置 $connection = new AMQPStreamConnection('192.168.33.1', 5672, 'zhangcs', 'zhangcs', '/'); $channel = $connection->channel(); // 通過隊列屬性設置隊列的過期時間為10s, 然后在管理頁面查看10s之后隊列是否消失 $arguments = new AMQPTable(); $arguments->set("x-expires", 10000); $queueName = 'test_queue_ttl'; $channel->queue_declare($queueName, false, true, false, false, false, $arguments); $channel->close(); $connection->close();
運行該代碼之后可以在web管理后台中發現增加了 test_queue_ttl 隊列,然后隊列特性中會有 Exp 標志,10 秒之后該隊列會被刪除。