程式碼概觀

開發人員 > 程式碼概觀

架構

以下章節將逐步介紹 Apache ActiveMQ Classic 的主要部分,並連結到程式碼,以幫助您了解其佈局

JMS 用戶端

org.apache.activemq 套件定義了核心 JMS 用戶端。

傳輸

JMS 用戶端和訊息代理程式使用 Transport 抽象概念來傳送命令物件(類似於分散式的命令模式)。TransportChannel 通常處理某種網路機制(使用 BIO 的 TCP 通訊端、使用 NIO、UDP / 多播、透過通訊端的 SSL、JXTA、EmberIO 等)。詳情請參閱 org.apache.activemq.transport 套件

因此,TransportChannel 主要負責傳送和接收 Command 物件(每個實例代表某種命令)。封包在 org.apache.activemq.command 套件中定義,該套件定義了所有 JMS 訊息實作類別(即命令),以及許多其他類型的封包,例如訂閱、訊息確認、交易等等。

線路格式

有多種方法可以將訊息編碼到串流中。我們可能希望適應各種不同的編碼機制 - 例如,為與 C / JavaScript 對話提供更簡單的線路格式,或製作 C# 友好的編碼。

因此,所有 Transport 實作都採用可插入的 WireFormat 實作類別 - 這是用於決定如何將 Command 寫入 DataIn / DataOut 串流或資料報的策略模式

因此,如果您希望提供自己的二進位線上協定,那麼我們只需要您的協定的 WireFormat 實作,然後我們可以將其與任何傳輸(TCP BIO、NIO、JXTA 等)一起使用。

我們預設使用 OpenWireFormat,這是 Java 程式碼中使用最有效率且最簡單的格式 - 因此,如果線路的兩端都是 Java,則強烈建議使用。不過,我們非常歡迎其他 WireFormat。

預設線路格式

預設線路格式會寫入一個位元組,表示要傳送的 Command 類型(請參閱 CommandTypes 介面,該介面定義了每種命令類型的所有 int 常數)。

核心 JMS 訊息類型各有唯一的位元組 ID,適用於

  • Message
  • ObjectMessage
  • TextMessage
  • MapMessage
  • BytesMessage
  • StreamMessage

此外,還有其他各種 命令類型,例如

還有其他一些;org.apache.activemq.command 套件會詳細描述它們。

基本上,DefaultWireFormat 對每個命令都有預設編碼。因此,在寫入表示封包類型的第一個位元組之後,每個封包類型都有特定的線路格式。

對於新的線路格式,您可能只需要支援這些類型的一小部分。例如,您可能只有一個簡單的發佈訊息、取用訊息和訊息確認。

訊息代理程式

訊息代理程式(JMS 用戶端的伺服器端)的 API 在 org.apache.activemq.broker 中定義。還有其他各種套件定義了不同的部分,從訊息儲存到訊息路由等等。

若要查看這些套件的概觀,請嘗試 JavaDocs


ActiveMQ Classic 系統概觀

簡介

ActiveMQ Classic 是負責建立和管理用戶端與代理程式之間通訊所用網路連線的系統。本文檔旨在概述此系統的內部運作方式,以便讓未來的開發人員更容易理解。它將對系統進行高階概述,並概述主要參與者。我們還將介紹一些其他可能對系統開發人員有用的有趣類別。本文檔的大部分內容都是以伺服器端程式碼為考量撰寫的。這是因為用戶端通訊系統的架構很簡單,而且了解伺服器會讓了解用戶端變得微不足道。

我們假設讀者對 JMS 有基本的了解。如需詳細資訊,請參閱官方 Java 文件。

概觀:主要參與者

ActiveMQ Classic 通訊系統中涉及的核心類別是傳輸。這些類別包括 TransportTransportServerTransportFactory 階層。TransportTransportServer 分別是通訊端和伺服器通訊端的包裝函式。TransportFactory(您可能猜到了)是建立 TransportTransportServer 的工廠。Transport 連接到 Broker 並傳輸 Command,它代表 ActiveMQ Classic 要執行的所有主要動作(稍後會詳細介紹)。以下範例說明這些部分如何結合在一起。

建立 JMS「提供者」應用程式所需的主要類別是 Broker 類別。預設的 ActiveMQ Classic 二進位檔會使用 BrokerService 類別來包裝 Broker。當應用程式啟動時,它會實例化一個 BrokerService,並指示它繫結到特定的(本機)位址,例如「tcp://127.0.0.1:61616」。Broker 會使用給定位址中的配置,並找到正確的 TransportFactory,在此範例中為 TcpTransportFactory。然後,這個工廠會用於建立將繫結到「localhost:61616」的 TcpTransportServer。一旦 TransportServer 啟動,它會持續輪詢其通訊端以取得傳入的連線。成功連接的傳入通訊端將會包裝在 TcpTransport 實例中,並(間接)傳回給 BrokerBroker 接著會開始輪詢新的 Transport,以取得要處理的傳入 Command

上述範例中遺失的最後一部分是 TransportConnectionTransportConnector 類別。這些類別用於將 Broker 分別連接到 TransportTransportServer

類別詳細資料

本節將分別說明上述類別的一些更有趣的詳細資料。

傳輸、TransportServer 和 TransportFactory

這些類別的運作基本原理非常簡單:TransportTransportServer 是通訊端和伺服器通訊端的包裝函式,用於隱藏實作,而 TransportFactory 是上述類別的工廠類別。唯一的注意事項是 TransportFactory 如何根據它們提供的 URI 來選擇和配置。

TransportFactory 類別是抽象的,無法直接建立 TransportTransportServer 類別。不過,它仍然是用來建立 TransportTransportServer 的類別。TransportFactory 會將其職責委派給其子類別,這是根據 FactoryFinder 類別提供的子類別選擇來委派的,該類別會使用 URI 的配置,根據儲存在 META-INF 目錄下的文字檔來尋找相符的工廠類別。

所建立的 Transport 的配置完全是透過反射來完成的。Transport 是透過呼叫 compositeConfigure 來配置的,這些呼叫是由工廠在建立 Transport 時進行的。compositeConfigure 使用 IntrospectionSupport 類別來呼叫 URI 中傳入參數的 setter。例如,使用 URI「ssl://127.0.0.1:61616/?needClientAuth=true」建立 Transport 會導致建立一個 SslTransport 物件,其 setNeedClientAuth 方法(如果存在)會在建立後立即呼叫並使用值 trueTransportServer 的運作方式類似。唯一的差異是,對 IntrospectionSupport 的呼叫是從 TransportFactorydoBind 方法發出的。

命令

CommandBroker 中通訊的主要方式。每個 Command 代表要執行的動作。Command 子類別包括 ConnectionInfoKeepAliveInfoMessage,它們會導致處理新連線、維護舊連線以及處理使用者訊息。這些類別是使用封送處理器從 Transport 取消序列化的。每當在通訊端中找到新資料時,會讀取第一個位元組,以判斷接收的 Command 類型。然後,會選取適當的封送處理器來取消序列化 Command(例如,若要取消序列化 ConnectionInfo,會使用 ConnectionInfoMarshaller)。

TransportConnections 和 TransportConnectors

每一個 TransportServer 都會使用一個 TransportConnector 連接到一個 Broker。伺服器的接受監聽器 (當一個新的 Transport 被建構時會被呼叫) 設定為呼叫給定的 TransportConnectorcreateConnection 方法,並帶入新的 Transport。當被呼叫時,createConnection 會建立一個新的 TransportConnection,將給定的 Transport 和支援的 Broker 連接在一起;Transport 的傳輸監聽器會設定為 TransportConnectiononCommand 方法,該方法會在收到新的 Command 時被呼叫。

CommandAbstractConnection (TransportConnection 的父類別) 形成一個訪問者模式。onCommand 會呼叫 AbstractConnection 的 service 方法,該方法會根據訪問者模式進行一系列的呼叫,最終將適當的 Command 子類別傳遞給 Broker 的相應方法進行處理。

BrokerFilters 和 BrokerPlugins

雖然通訊系統不直接使用 BrokerFilterBrokerPlugin,但它們提供了一種有效且易於使用的方法來修改 Broker 的行為。BrokerFilter 允許修改一些 Broker 的方法,而無需觸及其他部分 (顧名思義)。BrokerFilter 將其所有職責傳遞給在其建構函式中接收到的 Broker。繼承 BrokerFilter 允許我們在將工作傳遞給底層的 Broker 之前執行其他操作。

BrokerFilter 類別的強大之處在於可以串聯多個篩選器來創建不同的功能組合。例如,JaasAuthenticationBrokerBrokerFilter 的一個子類別,它修改用於新增和移除連線的方法,以允許 JAAS 身份驗證。AuthorizationBrokerBrokerFilter 的另一個子類別。這個類別修改目標規則方法來強制執行存取層級。透過這種架構,可以建立一個 JaasAuthenticationBroker,並讓它使用一個 AuthorizationBroker 作為其底層的 Broker (而該 Broker 本身又會使用另一個 Broker 等等)。

BrokerPlugin 是一個簡單的類別,它會將其對應的 Broker 包裝在其所給定的 Broker 周圍。也就是說,在現有的 Broker 上「安裝」一個 AuthorizationPlugin 將會建立一個 AuthorizationBroker,它在內部使用原始的 BrokerBrokerPlugin 存在的主要原因是允許使用者設定 BrokerService 類別使用的 Broker (透過程式碼或 XML 設定以及 Spring)。

Apache、ActiveMQ、Apache ActiveMQ、Apache 羽毛標誌和 Apache ActiveMQ 專案標誌是 The Apache Software Foundation 的商標。版權所有 © 2024,The Apache Software Foundation。根據 Apache License 2.0 授權。