朋友們大家好!在先前的討論中,我們深入研究了 Apache Camel 與 Quarkus 的集成,示範如何使用 Apache Camel 建立實際應用程式。當我們繼續我們的系列時,我們的目標是深入研究 Apache Camel 的關鍵組件和內在細節。
Apache Camel 的核心是圍繞 Gregor Hohpe 和 Bobby Woolf 所寫的 企業整合模式 (EIP) 書中介紹的概念構建的。本書概述了許多模式,這些模式已成為設計和記錄跨企業應用程式的強大整合解決方案的標準化
或系統。以下是 Apache Camel 中使用的一些關鍵模式的概述:
聚合器模式(圖 1)對於收集相關訊息並將其合併為一個有凝聚力的單一訊息,從而促進綜合處理至關重要。它充當專門的過濾器,累積相關訊息,直到收到完整的資料集,然後發布聚合輸出
以便進一步處理。
圖 1 – 聚合器模式 (enterpriseintegrationpatterns.com)
此模式(圖 2)會根據訊息內容動態地將訊息路由到適當的接收者。路由決策可以取決於各種訊息屬性,例如欄位存在或特定欄位值。
圖 2 – 內容為基礎的路由器模式 (enterpriseintegrationpatterns.com)
動態路由器(圖 3)有助於在運行時做出路由決策,根據外部定義的規則或透過使用者輸入進行動態調整,支援現代面向服務的架構。
圖 3 – 動態路由器模式 (enterpriseintegrationpatterns.com)
訊息過濾器(圖 4)將訊息定向到輸出通道或根據指定條件丟棄它們,確保只有滿足特定條件的訊息才會被進一步處理。
圖 4 – 訊息過濾器模式 (enterpriseintegrationpatterns.com)
此模式(圖 5)編排業務流程中的步驟序列,處理執行順序和任何發生的異常。它支援複雜的工作流程,其中順序處理和錯誤管理至關重要。
圖 5 – 流程管理器模式 (enterpriseintegrationpatterns.com)
規範化器模式(圖 6)是 Apache Camel 中的關鍵工具,可解決不同系統之間訊息格式差異的挑戰。它接收各種格式的傳入訊息,並在進一步處理之前將其轉換為標準化格式,從而確保整個資料處理管道的一致性。這種模式在訊息來自不同來源且格式不同的環境中特別有用。
圖 6 – 標準化器模式 (enterpriseintegrationpatterns.com)
Splitter 模式簡化了處理由多個資料項目組成的複雜訊息(圖 7)。此模式有效地將複合訊息劃分為其組成元素,從而允許獨立處理每個元素。這在訊息的不同部分需要根據其各自的特徵進行不同的路由或處理的情況下非常有用。
圖 7 – 分離器模式 (enterpriseintegrationpatterns.com)
我必須提的是,這些只是 Apache Camel 中使用的一些模式。 Apache Camel 中也使用了更多模式。但我認為這些模式才是最重要的。
本質上,Apache Camel 框架以強大的路由引擎為中心,或者更準確地說,以路由引擎建構器為中心。該引擎使開發人員能夠設計客製化的路由規則,確定從哪些來源接受訊息,並定義如何處理這些訊息並將其分派到各個目的地。 Apache Camel 透過類似複雜業務流程中的整合語言來支援複雜路由規則的定義。
Camel 的基本原則之一是其與資料無關的性質。這種靈活性至關重要,因為它允許開發人員與任何類型的系統進行交互,而無需嚴格要求將資料轉換為預先定義的規範格式。無縫處理不同資料形式的能力使 Camel 成為任何系統整合商工具包中的多功能工具。
在 Apache Camel 領域,訊息是透過訊息通道促進系統之間通訊的基本實體。這些組件如圖 8 所示。在路由執行的過程中,訊息可以經歷各種轉換-它們可以被更改、複製、
或根據過程的具體需要完全替換。訊息本質上是從發送者單向流向接收者,並包含多個元件:
正文(Payload):訊息的主要內容。
標頭: 與訊息關聯的元數據,其中可以包含鍵及其各自的值。
附件:可以與訊息一起傳送的選用檔案。
圖 8 – Apache Camel 訊息結構
Apache Camel 中的訊息由 java.lang.String 類型的識別碼唯一識別。此識別符的唯一性由訊息創建者強制執行,並且取決於所使用的協議,儘管格式本身並未標準化。對於缺乏唯一訊息識別方案的協議,Camel 使用自己的 ID 產生器。Camel 訊息中的標頭充當鍵值對,其中包含寄件者識別碼、有關內容編碼的提示、身份驗證資料等元資料。每個標頭名稱都是一個唯一的、不區分大小寫的字串,而值可以是任何物件(java.lang.Object),體現了Camel對標頭類型的靈活處理。所有標頭都作為映射儲存在訊息中。
此外,訊息可能包含選購配件,通常在涉及網路服務和電子郵件交易的上下文中使用。訊息正文也是 java.lang.Object 類型,是通用的,可容納任何形式的內容。這種靈活性要求應用程式設計者確保不同系統之間內容的可理解性。為了幫助實現這一點,Camel 提供了各種機制,包括必要時的自動類型轉換,將資料轉換為發送者和接收者相容的格式,從而促進跨不同環境的無縫資料整合。
交換
圖 9)所示,它封裝了一條訊息,透過 Camel 路由中的一系列預定義步驟支援訊息的轉換和處理。 Exchange 實作了以下 org.apache.camel.Exchange 介面。
圖 9 – Apache Camel 交換
Exchange 旨在適應不同風格的訊息傳遞,特別強調請求-回覆模式。如果在訊息處理過程中出現異常,它足夠強大,可以攜帶有關故障或錯誤的資訊。
交易所ID:這是交易所的唯一標識符,由Camel自動產生以確保可追溯性..
訊息交換模式 MEP: 指定訊息傳遞樣式,InOnly 或 InOut。對於 InOnly,事務僅涉及傳入訊息。對於 InOut,存在附加的傳出訊息(Out Message),用於將回應轉寄回發起者。
異常 - Exchange 擷取路由期間發生的異常,集中錯誤管理以便於處理和緩解。
正文:每個訊息(輸入和輸出)都包含 java.lang.Object 類型的有效負載,允許多種內容類型。
標頭: 儲存為映射,標頭包括與訊息關聯的鍵值對,攜帶元數據,例如路由提示、驗證金鑰和其他上下文資訊。
屬性: 與標頭類似,但在整個交換過程中持續存在,屬性在整個訊息處理生命週期中保存相關的全域層級資料。
訊息中: 基礎元件,此強制元素封裝來自入站通道的傳入請求資料。
Out message: InOut 交換中存在的選用元件,將回應資料攜帶到出站通道。
在 Apache Camel 中,Exchange 是一個訊息容器,它透過 Camel 路由攜帶資料。它封裝訊息並允許它透過 Camel 路由中定義的一系列處理步驟進行轉換和處理。 Exchange 也促進了請求-回覆訊息傳遞的模式,如果在訊息處理過程中發生異常,則可能會攜帶故障或錯誤訊息。
Apache Camel 上下文是 Apache Camel 中的一個基本元素,作為編排整合框架功能的核心架構。它是路由規則、配置、元件和其他整合元素匯聚的地方。 Camel Context(圖 10)初始化、設定和監督其包含的所有元件和路由的生命週期。
圖 10 – Apache Camel 上下文
在 Camel 上下文中,促進了以下關鍵操作:
載入元件和資料格式:這涉及到跨不同路由使用的元件和資料格式的初始化和可用性管理。
設定路由:它提供了一種定義訊息所遵循路徑的機制,包括如何在不同端點之間處理和中介訊息的規則。
啟動和停止路由:Camel 上下文管理路由的啟動和停用,確保這些操作以執行緒安全的方式執行。
錯誤處理:實作集中式錯誤處理機制,可以在上下文中的所有路由上使用。
管理資源:確保有效管理執行緒池或連線等資源,在不再需要時適當釋放它們。
Camel 上下文可以透過程式設計或聲明方式進行設定。例如,在基於 Java 的設定中:
import org.apache.camel.CamelContext; import org.apache.camel.impl.DefaultCamelContext; public class MainApp { public static void main(String[] args) { CamelContext camelContext = new DefaultCamelContext(); try { // Add routes, components, etc. camelContext.start(); Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } finally { try { camelContext.stop(); } catch (Exception e) { // Handle exception } } } }
對於像 Quarkus 這樣的環境,Camel 上下文通常會如下檢索和管理:
@Inject CamelContext context; if (context.isStarted()) { context.getRouteController().startRoute("start_route"); }
利用 Quarkus 時,Camel 情境會自動設定與管理:
@ApplicationScoped public class DemoRoute extends RouteBuilder { @Override public void configure() throws Exception { from("direct:start_route") .log("Starting route: ${routeId}, headers: ${headers}") .setHeader("header_abc", constant("header_value")) .to("direct:route_1") .to("direct:route_3"); } }
在 Apache Camel 中,端點表示用於連接 Camel 應用程式與外部系統或服務的介面。它們是路線開始(消耗)或結束(生產)的點。
一些常見的端點類型包括:
// Route to read files from the directory "input" and move processed files to "output" from("file:input?move=processed") .to("file:output");
// Route to consume data from an HTTP service from("timer:foo?period=60000") .to("http://example.com/api/data") .to("log:result");
// Using direct for synchronous call from("direct:start") .to("log:info");
Camel 中的路由定義了端點之間的訊息流,包含一系列處理器或轉換。它們對於在 Camel 應用程式中建立處理邏輯至關重要。
這是一個示範一系列互連路線的範例:
@ApplicationScoped public class DemoRoute extends RouteBuilder { @Override public void configure() throws Exception { from("direct:start_route") .log("Starting route: ${routeId}, headers: ${headers}") .setHeader("header_abc", constant("header_value")) .to("direct:route_1") .to("direct:route_3"); from("direct:route_1") .log("Starting route_1: ${routeId}, headers: ${headers}, thread: ${threadName}") .process( exchange -> { exchange.getIn().setHeader("header_abc", "UPDATED_HEADER_VALUE"); }) .to("direct:route_2"); from("direct:route_2") .log("Starting route_2: ${routeId}, headers: ${headers}, thread: ${threadName}"); } }
這裡第一個路由從 direct:start_route 端點開始,記錄 RouteId 和 headers,使用 key: header_abc 設定新的 header,然後將訊息轉送到下一個路由 direct:route_1。第二個路由記錄routeId、標頭和執行緒名稱,然後將訊息轉送到下一個路由direct:route_2。第三條路由記錄了routeId、標頭和線程名稱。
在對 Apache Camel 的詳細探索中,我們遍歷了使其成為企業整合領域不可或缺的工具的核心概念和基本組件。從對企業整合模式 (EIP) 的徹底檢查開始,我們了解了 Camel 如何利用聚合器、分割器和規範器等模式來有效解決常見的整合挑戰。
此外,我們深入研究了 Camel 的架構基礎,強調了它的多功能路由功能、靈活的訊息模型以及 Camel 上下文在管理和編排這些元素方面的關鍵作用。我們也介紹了實際方面,示範如何定義和管理路由,以及了解促進與外部系統通訊的各種端點類型。
以上是探索 Apache Camel 的核心功能和元件的詳細內容。更多資訊請關注PHP中文網其他相關文章!