天天看點

【原創】RabbitMQ 之 TTL 詳解(翻譯)

rabbitmq allows you to set time to live for both messages and queues.

rabbitmq 允許你針對 message 和 queue 設定 ttl 值。

the x-message-ttl argument to queue.declare controls for how long a message published to a queue can live before it is discarded. ttl can be set for a given queue by setting the x-message-ttl argument to queue.declare, or by setting the message-ttl policy.a message that has been in the queue for longer than the configured ttl is said to be dead. note that a message routed to multiple queues can die at different times, or not at all, in each queue in which it resides. the death of a message in one queue has no impact on the life of the same message in other queues.

the server guarantees that dead messages will not be included in any basic.get-ok or basic.deliver methods. further, the server will try to reap messages at or shortly after their ttl-based expiry.

伺服器會保證“死掉”的 message 将不會在任何 basic.get-ok 或 basic.deliver 方法中被包含。更進一步,伺服器将努力在 ttl 到期或到期後的短時間内處理掉該 message 。 

the value of the x-message-ttl argument must be a non-negative 32 bit integer (0 <= n <= 2^32-1) the value of the ttl argument or policy must be a non-negative integer (0 <= n), describing the ttl period in milliseconds. thus a value of 1000 means that a message added to the queue will live in the queue for 1 second or until it is delivered to a consumer. the argument can be of amqp type short-short-int, short-int, long-int, or long-long-int.

參數 x-message-ttl 的值必須是非負的 32 位整數 (0 <= n <= 2^32-1) 作為 argument 或 policy 的 ttl 的值必須為非負整數(0<=n),以毫秒為機關表示 ttl 的值。這樣,值 1000 表示存在于 queue 中的目前 message 将最多隻存活 1 秒鐘,除非其被投遞到 consumer 上。實參可以是以下 amqp 類型:short-short-int 、short-int 、long-int 或者 long-long-int 。 

this example in java creates a queue in which messages may reside for at most 60 seconds:

下面的 java 執行個體代碼建立了一個 queue ,且 message 在該 queue 的存活時間最大為 60 秒: 

<a href="http://my.oschina.net/moooofly/blog/101765#">?</a>

1

2

3

<code>map&lt;string, object&gt; args =</code><code>new</code> <code>hashmap&lt;string, object&gt;();</code>

<code>args.put(</code><code>"x-message-ttl"</code><code>,</code><code>60000</code><code>);</code>

<code>channel.queuedeclare(</code><code>"myqueue"</code><code>,</code><code>false</code><code>,</code><code>false</code><code>,</code><code>false</code><code>, args);</code>

to specify a ttl using policy, add the key "message-ttl" to a policy definition. for example:

若想要通過 policy 設定 ttl ,則需要将 key 值 message-ttl 添加到 policy 定義中,例如:

rabbitmqctl

rabbitmqctl set_policy ttl ".*" '{"message-ttl":60000}' --apply-to queues

rabbitmqctl (windows)

rabbitmqctl set_policy ttl ".*" "{""message-ttl"":60000}" --apply-to queues

this applies a ttl of 60 seconds to all queues. 

上述指令設定所有 queue 的 ttl 均為 60 秒。 

the original expiry time of a message is preserved if it is requeued (for example due to the use of an amqp method that features a requeue parameter, or due to a channel closure). 

當 message 被 requeue 的時候,其原始過期時間将被保留(例如由于設定了 requeue 參數的 amqp 方法的使用,或者由于 channel 的關閉)。 

setting x-message-ttl the ttl to 0 causes messages to be expired upon reaching a queue unless they can be delivered to a consumer immediately. thus this provides an alternative to basic.publish's immediate flag, which the rabbitmq server does not support. unlike that flag, no basic.returns are issued, and if a dead letter exchange is set then messages will be dead-lettered. 

設定 x-message-ttl ttl 為 0 則表示,在 message 到達 queue 之後,若未被立即投遞到 consumer ,則立即将其判定為過期。這種方式相當于 rabbitmq server 不支援 basic.publish 中 immediate 辨別情況下的等價實作。與采用 immediate 屬性的方式不同的是,将不會有 basic.returns 指令的調用,并且在設定了 dead letter exchange 的情況下,這些 message 将被處理為 dead-lettered 。

a ttl can be specified on a per-message basis, by setting the expiration field in the basic amqp class when sending a basic.publish.

ttl 設定可以具體到每一條 message 本身,隻要在通過 basic.publish 指令發送 message 時設定 expiration 字段。 

the value of the expiration field describes the ttl period in milliseconds. the same constraints as for x-message-ttl apply. since the expiration field must be a string, the broker will (only) accept the string representation of the number.

expiration 字段以毫秒為機關表示 ttl 值。且與 x-message-ttl 具有相同的限制條件。因為 expiration 字段必須為字元串類型,broker 将隻會接受以字元串形式表達的數字。 

when both a per-queue and a per-message ttl are specified, the lower value between the two will be chosen.

當同時指定了 queue 和 message 的 ttl 值,則兩者中較小的那個才會起作用。 

this example in java publishes a message which can reside in the queue for at most 60 seconds:

下面的 java 示例 publish 了最多能在 queue 中存活 60 秒的 message : 

4

<code>byte</code><code>[] messagebodybytes =</code><code>"hello, world!"</code><code>.getbytes();</code>

<code>amqp.basicproperties properties =</code><code>new</code> <code>amqp.basicproperties();</code>

<code>properties.setexpiration(</code><code>"60000"</code><code>);</code>

<code>channel.basicpublish(</code><code>"my-exchange"</code><code>,</code><code>"routing-key"</code><code>, properties, messagebodybytes);</code>

while consumers never see expired messages, only when expired messages reach the head of a queue will they actually be discarded (or dead-lettered). when setting a per-queue ttl this is not a problem, since expired messages are always at the head of the queue. when setting per-message ttl however, expired messages can queue up behind non-expired ones until the latter are consumed or expired. hence resources used by such expired messages will not be freed, and they will be counted in queue statistics (e.g. the number of messages in the queue).

雖然 consumer 從來看不到過期的 message ,但過期 message 隻會在到達 queue 的頭部時才會被真正的丢棄(或者 dead-lettered )。當采用針對 queue 設定 ttl 的方式時,不會産生任何問題,因為過期的 message 總是會出現在 queue 的頭部。但是當針對每條 message 設定了 ttl 時,已過期 message 可能會排在未過期 message 的後面,直到後者被 consume 掉或者過期。在這種情況下,這些過期的 message 使用的資源将不會被釋放,且會在 queue 統計資訊中被計算進去(例如,queue 中存在的 message 的數量)。

the x-expires argument to queue.declare expiry time can be set for a given queue by setting the x-expires argument to queue.declare, or by setting the expires policy. this controls for how long a queue can be unused before it is automatically deleted. unused means the queue has no consumers, the queue has not been redeclared, and basic.get has not been invoked for a duration of at least the expiration period. this can be used, for example, for rpc-style reply queues, where many queues can be created which may never be drained.

queue.declare 指令中的 x-expires 參數 可以通過設定 x-expires 參數給 queue.declare 方法,或者設定名為 expires 的 policy 來設定過期時間,進而控制 queue 被自動删除前可以處于“未使用”狀态的時間。“未使用”的意思是指 queue 上沒有任何 consumer ,且在過期時間段内 queue 沒有被重新聲明,也未通過 basic.get 指令被通路過。該方式可用于,例如,rpc-style 的回複 queue ,其中許多 queue 會被建立出來,但是卻從未被使用。 

the server guarantees that the queue will be deleted, if unused for at least the expiration period. no guarantee is given as to how promptly the queue will be removed after the expiration period has elapsed. leases of durable queues restart when the server restarts.

伺服器會確定在過期時間到達後 queue 被删除,但是不保證删除的動作有多麼的及時。在伺服器重新開機後,持久化的 queue 的逾時時間将重新計算。 

the value of the x-expires argument or expires policy describes the expiration period in milliseconds and is subject to the same constraints as x-message-ttl and cannot be zero . it must be a positive integer (unlike message ttl it cannot be 0). thus a value of 1000 means a queue which is unused for 1 second will be deleted.

x-expires 參數的值或者 policy 中的 expires 的值用于表示超期時間,以毫秒為機關。并且服從和 x-message-ttl 一樣的限制條件,且不能設定為 0 。該值必須為正數(與消息 ttl 不同,該值不可以為 0),是以如果該參數設定為 1000 ,則表示該 queue 如果在 1 秒鐘之内未被使用則會被删除。 

this example in java creates a queue which expires after it has been unused for 30 minutes.

下面的 java 示例建立了一個 queue ,其會在 30 分鐘不使用的情況下判定為逾時。 

<code>args.put(</code><code>"x-expires"</code><code>,</code><code>1800000</code><code>);</code>

the following policy does the same thing for all queues:

下面的 policy 設定可以實作和上面相同的功能:

rabbitmqctl set_policy expiry ".*" '{"expires":1800000}' --apply-to queues

rabbitmqctl set_policy expiry ".*" "{""expires"":1800000}" --apply-to queues