訊息在傳送時可以設定選擇性的存活時間。
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-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
),以便 Broker 自動建立 address
和 queue
來處理過期訊息。建立的 address
將是由 expiry-address
定義的位址。將在該 address
上建立 MULTICAST
queue
。它將使用先前傳送訊息的 address
來命名,並且會使用屬性 _AMQ_ORIG_ADDRESS
定義一個篩選器,以便它只接收傳送到相關 address
的訊息。可以使用前置詞和後置詞來設定 queue
名稱。請參閱下表中的相關設定
位址設定 |
預設值 |
---|---|
|
|
|
(空字串) |
以下是一個配置範例
<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
以停用清理執行緒)