訊息在傳送時可以設定選擇性的存活時間

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 允許為其傳送的訊息設定 TimeToLive

// 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",並且收到一則使用預設到期時間(即 0)的訊息,則其到期時間 "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),以便 Broker 自動建立 addressqueue 來處理過期訊息。建立的 address 將是由 expiry-address 定義的位址。將在該 address 上建立 MULTICAST queue。它將使用先前傳送訊息的 address 來命名,並且會使用屬性 _AMQ_ORIG_ADDRESS 定義一個篩選器,以便它只接收傳送到相關 address 的訊息。可以使用前置詞和後置詞來設定 queue 名稱。請參閱下表中的相關設定

位址設定 預設值

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 設定和使用訊息過期。