发送消息时可以为消息设置可选的生存时间

Apache ActiveMQ Artemis 不会在消息的生存时间超过后将其传递给消费者。如果消息在生存时间到达时尚未传递,则服务器可以将其丢弃。

Apache ActiveMQ Artemis 的地址可以分配一个过期地址,以便当消息过期时,它们将从队列中删除并发送到过期地址。许多不同的队列可以绑定到一个过期地址。这些过期的消息以后可以被消费,以便进行进一步检查。

1. 核心 API

使用 Apache ActiveMQ Artemis 核心 API,您可以直接在消息上设置过期时间

// message will expire in 5000ms from now
message.setExpiration(System.currentTimeMillis() + 5000);

JMS MessageProducer 允许为它发送的消息设置生存时间

// messages sent by this producer will be retained for 5s (5000ms) before expiration
producer.setTimeToLive(5000);

过期消息将获得 特殊属性 以及此附加属性

_AMQ_ACTUAL_EXPIRY

一个包含过期消息的实际过期时间的 Long 属性

2. 配置过期延迟

可以在地址设置配置中配置默认过期延迟

<!-- expired messages in exampleQueue will be sent to the expiry address expiryQueue -->
<address-setting match="exampleQueue">
   <expiry-address>expiryQueue</expiry-address>
   <expiry-delay>10</expiry-delay>
</address-setting>

expiry-delay 定义了将用于使用默认过期时间(即 0)的消息的过期时间(以毫秒为单位)。

例如,如果 expiry-delay 设置为“10”,并且使用默认过期时间(即 10)的消息到达,则其过期时间“0”将更改为“10”。但是,如果使用 20 的过期时间的消息到达,则其过期时间将保持不变。将 expiry-delay 设置为“-1”将禁用此功能。

默认值为 -1

如果未设置expiry-delay,则可以在地址设置配置中配置最小和最大过期延迟值。

<address-setting match="exampleQueue">
   <min-expiry-delay>10</min-expiry-delay>
   <max-expiry-delay>100</max-expiry-delay>
</address-setting>

语义如下

  • 没有过期时间的邮件将设置为 max-expiry-delay。如果未定义 max-expiry-delay,则邮件将设置为 min-expiry-delay。如果未定义 min-expiry-delay,则邮件不会更改。

  • 过期时间高于max-expiry-delay 的邮件将设置为 max-expiry-delay

  • 过期时间低于min-expiry-delay 的邮件将设置为 min-expiry-delay

  • 过期时间min-expiry-delaymax-expiry-delay 范围内的邮件将不会更改

  • expiry-delay 设置的任何值(除默认值外,即 -1)将覆盖上述最小/最大设置。

min-expiry-delaymax-expiry-delay 的默认值均为 -1(即禁用)。

3. 配置过期地址

过期地址在地址设置配置中定义

<!-- expired messages in exampleQueue will be sent to the expiry address expiryQueue -->
<address-setting match="exampleQueue">
   <expiry-address>expiryQueue</expiry-address>
</address-setting>

如果消息过期并且未指定过期地址,则消息将简单地从队列中删除并丢弃。地址 通配符 可用于为一组地址配置过期地址。

如果使用通配符为一组地址配置过期地址,并且您希望为特定地址(或一组地址)取消设置过期地址,则可以执行此操作,例如

<address-setting match="#">
   <expiry-address>expiryQueue</expiry-address>
</address-setting>
<address-setting match="exampleQueue">
   <expiry-address/> <!-- unset expiry-address so messages which expire from queues bound to matching addresses are dropped -->
</address-setting>

4. 配置自动创建过期资源

通常,会按其原始地址对过期消息进行隔离。例如,发送到 stocks 地址的消息由于某种原因而过期,最终可能会路由到 EXP.stocks 队列,同样,发送到 orders 地址的消息过期后可能会路由到 EXP.orders 队列。

使用这种模式可以轻松跟踪和管理过期消息。但是,这在主要使用自动创建的地址和队列的环境中会带来挑战。通常,这些环境中的管理员不想手动创建 address-setting 来配置 expiry-address,更不用说实际的 addressqueue 来保存过期消息了。

解决此问题的方法是将 auto-create-expiry-resources address-setting 设置为 true(默认情况下为 false),这样代理将自动创建 addressqueue 来处理过期消息。创建的 address 将是 expiry-address 定义的 address。一个 MULTICAST queue 将在该 address 上创建。它将以发送消息的 address 命名,并将使用属性 _AMQ_ORIG_ADDRESS 定义一个过滤器,以便它只接收发送到相关 address 的消息。queue 名称可以使用前缀和后缀进行配置。请参阅下表中的相关设置

address-setting default

expiry-queue-prefix

EXP.

expiry-queue-suffix

(空字符串)

以下是一个配置示例

<address-setting match="#">
   <expiry-address>expiryAddress</expiry-address>
   <auto-create-expiry-resources>true</auto-create-expiry-resources>
   <expiry-queue-prefix></expiry-queue-prefix> <!-- override the default -->
   <expiry-queue-suffix>.EXP</expiry-queue-suffix>
</address-setting>

保存过期消息的队列可以通过以下方式直接访问:使用队列的名称本身(例如,当使用核心客户端时)或使用完全限定的队列名称(例如,当使用 JMS 客户端时),就像任何其他队列一样。此外,请注意,队列是自动创建的,这意味着它将根据相关的 address-settings 自动删除。

5. 配置过期清理线程

一个清理线程将定期检查队列,以查看消息是否已过期。

可以在 broker.xml 中使用以下属性配置清理线程

message-expiry-scan-period

扫描队列以检测过期消息的频率(以毫秒为单位,默认值为 30000 毫秒,设置为 -1 可禁用清理线程)

6. 示例

请参阅 消息过期示例,其中展示了如何使用 JMS 配置和使用消息过期。