預先提取限制是什麼?

ActiveMQ Classic 的其中一個設計目標是成為高效能訊息匯流排。這表示使用 SEDA 架構來盡可能非同步地執行工作。為了有效利用網路資源,代理程式採用「推播」模型將訊息派送給消費者。這確保了消費者始終有一個本地訊息緩衝區準備處理。另一種方法是消費者從代理程式明確地拉取訊息。單獨拉取訊息的效率不高,並且會顯著增加每個訊息的延遲。

然而,如果沒有限制推送到消費者的訊息數量,可能會耗盡其用戶端資源。這是訊息消耗速度通常比訊息傳遞速度慢得多的自然結果。為了避免這種情況,ActiveMQ Classic 因此採用預先提取限制來限制一次最多可以派送給單個消費者的訊息數量。消費者反過來使用預先提取限制來調整其預先提取訊息緩衝區的大小。

一旦代理程式向消費者派送了預先提取限制數量的訊息,它將不會再向該消費者派送任何訊息,直到消費者確認收到至少 50% 的預先提取訊息,例如,預先提取/2。當代理程式收到上述確認時,它將向消費者派送進一步的預先提取/2 數量的訊息,以「補充」其預先提取緩衝區。請注意,可以根據每個消費者指定預先提取限制(請參閱下文)。

建議對於高訊息量的高效能使用較大的預先提取值。但是,對於每個訊息需要很長時間處理的較低訊息量,預先提取應設定為 1。這可確保消費者一次只處理一個訊息。但是,將預先提取限制指定為零將導致消費者一次輪詢一條訊息,而不是將訊息推送到消費者。

什麼是慢速消費者?

慢速消費者是指有超過其設定的預先提取限制數量兩倍的待處理訊息的消費者。

使用動態語言實作消費者

無法快取預先提取訊息的消費者必須將其預先提取設定為 1。例如,使用 Ruby 等指令碼語言透過 STOMP 連線實作的消費者就是這樣的一個範例。在這種情況下,沒有用戶端訊息緩衝區的概念。

指定 PrefetchPolicy

您可以在 ActiveMQPrefetchPolicy 的實例上指定 ActiveMQConnectionFactoryActiveMQConnection。這允許您設定所有個別預先提取值;因為每個不同的服務品質都有不同的值。例如:

  • 持久佇列 (預設值:1000)

  • 非持久佇列 (預設值:1000)

  • 持久主題 (預設值:100)

  • 非持久主題 (預設值:Short.MAX_VALUE - 1)

預先提取限制也可以在用於建立與代理程式連線的連線 URI 上設定。要變更所有消費者類型的預先提取限制,請如下設定連線 URI

tcp://127.0.0.1:61616?jms.prefetchPolicy.all=50

若要僅變更佇列消費者的預先提取限制,請如下設定連線 URI

tcp://127.0.0.1:61616?jms.prefetchPolicy.queuePrefetch=1

也可以使用 目的地選項 針對每個消費者設定

queue = new ActiveMQQueue("TEST.QUEUE?consumer.prefetchSize=10");
consumer = session.createConsumer(queue);

集區消費者和預先提取

由於預先提取,從集區的消費者使用訊息可能會產生問題。未使用的預先提取訊息僅在關閉消費者時釋放,但對於集區消費者,關閉會延遲(以供重複使用),直到消費者集區關閉為止。這使得預先提取的訊息未被使用,直到消費者被重複使用。從效能的角度來看,此功能可能是可取的。但是,當集區中有一個以上的消費者時,可能會導致訊息傳遞順序混亂。因此,org.apache.activemq.pool.PooledConnectionFactory 不會集區消費者。

Springs CachingConnectionFactory 支援集區消費者 (雖然預設情況下已關閉)。如果您在 Springs DefaultMessageListenerContainer (DMLC) 中設定了多個消費者執行緒來使用 CachingConnectionFactory,那麼您可能需要關閉 CachingConnectionFactory 中的消費者集區 (預設情況下已關閉),或者您可能希望在使用集區消費者時使用預先提取值 0。這樣,消費者將在每次呼叫 receive(timeout) 時輪詢訊息。一般建議關閉 Spring CachingConnectionFactory 和任何其他允許集區 JMS 消費者的架構中的消費者快取。

請注意,Springs DefaultMessageListenerContainer (DMLC) 及其 CACHE_CONSUMER 快取層級不受此問題影響!Springs DMLC 不會以使用多個消費者實例的內部集區的意義來集區消費者。相反,它會快取消費者,也就是說,它會重複使用相同的 JMS 消費者物件來接收 DMLC 執行個體生命週期中的所有訊息。因此,它的行為與手寫的 JMS 程式碼非常相似,您可以在其中建立 JMS 連線、工作階段、消費者,然後使用此消費者實例來接收所有訊息。
因此,即使使用多個消費者執行緒,在 Springs DMLC 中使用 CACHE_CONSUMER 也沒有問題,除非您使用 XA 交易。XA 交易不適用於 CACHE_CONSUMER。但是,可以使用本機 JMS 交易和非交易消費者在 Springs DMLC 中使用 CACHE_CONSUMER

另請注意,Camel 的 JMSActiveMQ Classic 組件在內部使用 Spring 的 DMLC。因此,上述關於 Spring DMLC 和 CACHE_CONSUMER 的所有內容也適用於這兩個 Camel 組件。

記憶體與效能的權衡

設定相對較高的預先提取值可帶來更高的效能。因此,預設值通常大於 1000,對於主題而言更高,而對於非持久性訊息則更高。預先提取大小決定了在用戶端 RAM 中將保留多少訊息,因此如果您的 RAM 有限,您可能需要設定一個較低的值,例如 1 或 10 等。

Apache、ActiveMQ、Apache ActiveMQ、Apache 羽毛標誌和 Apache ActiveMQ 專案標誌是 Apache 軟體基金會的商標。Copyright © 2024, The Apache Software Foundation。依 Apache License 2.0 授權。