【原创】RabbitMQ 之 TTL 详解(翻译)
【原创】RabbitMQ 之 TTL 详解(翻译)
摩云飞 发表于5年前
【原创】RabbitMQ 之 TTL 详解(翻译)
  • 发表于 5年前
  • 阅读 4514
  • 收藏 10
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

摘要: RabbitMQ官方文档中关于TTL的内容

Time-To-Live Extensions

RabbitMQ allows you to set Time To Live for both messages and queues.
RabbitMQ 允许你针对 message queue 设置 TTL 值。

Per-Queue Message 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.
通过在 queue.declare 中设置 x-message-ttl 参数,可以控制被 publish 到 queue 中的 message 被丢弃前能够存活的时间。可以通过设置名为 x-message-ttl 的 arugment 到 queue.declare ,或者通过设置名为 message-ttl policy来控制 queue 中 message 的存活时间。当某个 message 在 queue 留存的时间超过了配置的 TTL 值时,我们说该 message “已死”。值得注意的是,当一个 message 被路由到多个 queue 中时,其可以在不同的时间“死掉”,或者可能有的不会出现“死掉”情况。在某个 queue 中的某个 message 的“死亡”不会对相同 message 在其他 queue 中的生存状况产生影响。

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-okbasic.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 秒: 

Map<String, Object> args = new HashMap<String, Object>(); 
args.put("x-message-ttl", 60000); 
channel.queueDeclare("myqueue", false, false, false, args);

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 。

Per-Message TTL

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 : 

byte[] messageBodyBytes = "Hello, world!".getBytes(); 
AMQP.BasicProperties properties = new AMQP.BasicProperties(); 
properties.setExpiration("60000"); 
channel.basicPublish("my-exchange", "routing-key", properties, messageBodyBytes);

Caveats

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 的数量)。

Queue TTL

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 分钟不使用的情况下判定为超时。 

Map<String, Object> args = new HashMap<String, Object>(); 
args.put("x-expires", 1800000); 
channel.queueDeclare("myqueue", false, false, false, args);

The following policy does the same thing for all queues:

下面的 policy 设置可以实现和上面相同的功能:

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

标签: RabbitMQ TTL
共有 人打赏支持
粉丝 360
博文 352
码字总数 952596
×
摩云飞
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: