我應該如何使用 VM 傳輸
常見問題 > 使用 Apache ActiveMQ Classic > 我應該如何使用 VM 傳輸
適用於 ActiveMQ Classic 3.x/4.x
使用 VM 傳輸連線到 JVM 內部的代理程式是最快速且最高效的傳輸方式。
這是因為預設情況下,沒有序列化到 socket 或使用作業系統 socket 資源;它純粹是一個 JVM 內部的列表,用於與用戶端和代理程式交換訊息。有時您希望 VM 傳輸作為一個異步 SEDA 佇列工作;有時您希望內聯處理,以便減少執行緒上下文切換,這可以提高高效能場景中的吞吐量。
關於 VM 傳輸需要注意的一點是,訊息是以參考方式傳遞的。JMS ObjectMessage 是一個小例外。(請參閱下文,了解如何在 ActiveMQ Classic 4.x 中禁用它)
您還可以透過將 copyMessageOnSend 屬性設定為 false 來進一步優化,這樣可以避免複製 ObjectMessage 來傳送;儘管這假設您不會嘗試重複使用 ObjectMessage 實例;您只建立一次並傳送一次,並且在傳送後不會嘗試更改訊息的主體。
請小心 ClassLoader
請注意,只有當所有生產者和消費者都在相容的類別載入器中時,才應執行上述優化。例如,如果您有 2 個具有自己的 jar 檔的 WAR 檔彼此傳送訊息,則可能會由於同一個類別在每個類別載入器中載入而發生奇怪的 ClassCastExceptions;因此有時序列化 ObjectMessage 是一件好事,可以避免類別路徑混亂 - 因此只有在您確定您的類別路徑沒有問題時,才執行上述優化
使用 ObjectMessage 禁用 ActiveMQ Classic 4.x 的物件序列化
JMS 規範規定,當您呼叫 send() 時,必須序列化 ObjectMessage 的主體,以避免物件在您的眼皮底下改變而影響消費者看到的物件視圖。
您可以禁用 ObjectMessage 有效負載的自動序列化,以便在 4.x 中透過在 ActiveMQConnectionFactory (或 ActiveMQConnection) 上將 objectMessageSerializationDefered 標誌設定為 true 來按值傳遞物件。
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://127.0.0.1");
factory.setObjectMessageSerializationDefered(true);