发送消息时可以为消息设置可选的生存时间。
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-delay
和max-expiry-delay
范围内的邮件将不会更改 -
为
expiry-delay
设置的任何值(除默认值外,即-1
)将覆盖上述最小/最大设置。
min-expiry-delay
和 max-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
,更不用说实际的 address
和 queue
来保存过期消息了。
解决此问题的方法是将 auto-create-expiry-resources
address-setting
设置为 true
(默认情况下为 false
),这样代理将自动创建 address
和 queue
来处理过期消息。创建的 address
将是 expiry-address
定义的 address
。一个 MULTICAST
queue
将在该 address
上创建。它将以发送消息的 address
命名,并将使用属性 _AMQ_ORIG_ADDRESS
定义一个过滤器,以便它只接收发送到相关 address
的消息。queue
名称可以使用前缀和后缀进行配置。请参阅下表中的相关设置
address-setting |
default |
---|---|
|
|
|
(空字符串) |
以下是一个配置示例
<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
可禁用清理线程)