Camel 的 SEDA、Direct 和 VM 組件指南


Camel 的 SEDA、Direct 和 VM 組件指南

Apache Camel 中的 SEDA、Direct、Direct-VM 和 VM 組件、它們的作用以及何時可以使用它們。帶有代碼示例。

Camel 的 SEDA、Direct 和 VM 組件指南

在設計 Camel 路線時,您有時可能希望路線具有多個輸入。也許你想從Web服務接收消息JMS隊列

不能在同一個路由中有多個from()方法,那么你怎么能在同一個路由中有多個入口點呢?

同樣,您可能希望在多個地方重用相同的 Camel 消息處理邏輯,那么如何避免重復代碼呢?

這兩個問題的答案是使用 Camel 的內存中消息傳遞組件將您的路由連接在一起:Direct、Direct-VM、VM 和 SEDA。

在本文中,我將解釋這些組件中的每一個,它們有何不同,以及如何使用它們使您的路由更加模塊化和更棒。

首先……一個示例場景

首先,我將從一個例子開始。

我定義了一個路由,通過將消息傳遞給某個底層系統來驗證傳入的訂單。我的訂單最初是通過 JMS 消息到達的。

加入駱駝路線示例場景

但是,當訂單開始來自新來源(例如文件上傳或 Web 服務調用)時會發生什么?

為了避免重復相同的路由代碼,Camel 具有內置功能,允許路由具有多個輸入,通過使用一系列連接組件將這些路由粘合在一起。

那么它是怎樣工作的?Camel 使用組件 Direct、VM 和 SEDA 將端點粘合在一起。

這些組件以不同的方式將您的 Camel 路線連接在一起。它們統稱為 Camel 的內存中消息組件,因為它們允許消息在路由之間傳遞,而消息始終保留在內存中。這是一個非常重要的細節,我稍后會再次提及。

但是現在,讓我們看看這些組件中的每一個,看看它們有什么不同,以及您可以在哪里使用它們。

Direct component

這一定是 Camel 初學者最常問到的問題之一:

路徑中的“direct”是什么意思?

Camel 中的 Direct 組件

您可能已經在網絡上的許多 Camel 教程中看到過這些代碼direct:...。但direct實際上有什么作用呢?

Apache Camel 的Direct 組件是一種將路由連接在一起的方式。當它作為路由中的啟動組件使用時,可以從其他路由中調用,作為觸發路由的一種方式。由於 Direct 是一個同步組件,因此在同一線程中繼續執行。

direct是將您的路線鏈接在一起的最簡單的方法之一。當它在from()定義中使用時,它會創建一個可以被其他 Camel 路由調用的同步端點。例如,這段以from(direct)開頭的代碼:

from("direct:yourname")...

...將創建一個名為yourname. 這同一個端點然后可以在另一個被調用to()語句別的地方,就像這樣:

.to("direct:yourname");  // sends the message to the direct:yourname endpoint

在示例中,它經常被使用,因為它提供了一個簡單的路由入口點,而不必公開 Web 服務,或以其他方式依賴外部接口。

示例:使用 Direct 組件
讓我們用一個例子來說明 Direct 組件:
from("file:/home/files/in")       // receive a file
  .to("direct:processTheFile"); // send to direct endpoint
  .to("Body is now ${body}");   // will print 'Eggs!'

// meanwhile...    
from("direct:processTheFile")     // receive from direct endpoint
  .setBody("Eggs!");            // modify the message body</code>

但是,Direct 的簡單性也有一些缺點。

直接端點只能被在同一個 CamelContext和同一個 JVM中運行的其他路由訪問。這意味着您不能從另一個 CamelContext 訪問 Direct 端點。請記住,CamelContext 是創建和啟動 Camel 路由的容器。

那么如果你想訪問另一個 CamelContext 中的路由會發生什么?您使用下一個組件 Direct-VM。

這個非常簡單的示例使用 Camel 的 File 組件接收文件。處理的每個文件都作為 Exchange 傳遞到直接端點processTheFile

另外,我們已將processTheFile端點定義為修改消息正文的路由的起始組件。完成此操作后,新消息將返回到調用路由。所有這些都是在同一個線程中同步發生的。

Direct-VM component

Direct-VM 是一個組件,它允許您同步調用同一 JVM 中的另一個端點,即使它位於不同的CamelContext 中

當用作啟動組件時,Direct-VM 將該路由公開為可以從另一個路由同步調用的端點。

Direct-VM 組件的不同之處在於,direct-vm 端點可以從其他 Camel Contexts 中看到,只要它們共享相同的 Java 虛擬機 (JVM)。

示例:使用 Direct-VM 組件
如果我們想炫耀 Direct-VM 組件,我們可以在應用程序 A 中定義一個路由:

java from("file:src/files/input") .to("direct-vm:process-file") // invoke the direct-vm endpoint

這將調用此 Direct 端點,位於應用程序 B 中...

java from("direct-vm:process-file") // receive from direct-vm endpoint .to("log:samplelog"); // log the message

只要這兩個應用程序都在同一個 JVM 中運行——例如,在同一個 Spring Boot 應用程序中使用一個應用程序容器,如 Apache Karaf、Wildfly 甚至不同的 CamelContexts——那么應用程序 A 將能夠調用direct-vm應用程序中的端點B.

這開辟了將不在同一 CamelContext 中開發的路由鏈接在一起的可能性。例如,如果您在一個容器中部署了不同的 CamelContexts,您可能會使用此組件 - 例如當您部署到 JBoss FuseTalend ESB 時

SEDA組件

Camel 的 SEDA 組件允許您使用簡單的queue將路由連接在一起。

在 Camel 路由中,當消息被發送到 SEDA 端點時,它被存儲在一個基本的內存隊列中,並且控制立即返回到調用路由。

然后,SEDA 使用者獨立地從隊列中提取消息,並開始處理它。

示例:使用 SEDA 組件
下面是一個 SEDA 隊列的例子:

java rest("/orders").post() // receive an order via REST .to("seda:processOrder"); // send to the seda queue .setBody("Thanks for ordering!"); // create a REST response

from(“seda:processOrder”) // 從 seda 隊列接收 .log(“Processing an order…”) .to(“file:orders/out”);</code>

在上面的示例中,消息將通過 REST 服務接收並發布到 SEDA 端點。消息到達processOrderSEDA 端點並進行處理,然后使用該file:組件將它們寫入磁盤上的某個位置。

SEDA 通過創建自己的緩沖區來實現這一點,該緩沖區用於存儲傳入的消息。SEDA 開箱即用地創建了一個線程池來處理傳入的消息,這意味着可以一次處理多條消息,從而使其可能具有更高的性能。

通過這種方式,可以將 SEDA 視為 JMS 隊列的簡單替代品。它提供了類似隊列的功能,但沒有運行像 ActiveMQ 這樣的外部消息代理的開銷。

請記住,Camel 將消息異步發布到 SEDA 端點。

您只能訪問位於同一 CamelContext 中的SEDA 端點。那么如果你想向另一個 CamelContext 中的 SEDA 隊列發送消息會發生什么您使用下一個組件 VM。

VM component

與 Direct 和 Direct-VM 的關聯方式類似,VM 是與 SEDA 類似的組件。

當用作啟動組件時,SEDA 允許從另一個路由異步調用一個路由。

然而,SEDA 和 VM 之間的區別在於VM 組件允許從不同的 Camel 上下文訪問端點,只要它們運行在同一個 JVM 中即可。

同樣,VM 組件開啟了以異步方式將不在同一 Camel 上下文中開發的路由鏈接在一起的可能性。

SEDA 和 VM 的缺點

使用像 SEDA 和 VM 這樣的內存消息傳遞的最大缺點是,如果應用程序崩潰,很有可能會丟失所有消息

如果您設計的集成類型與消息丟失無關緊要,那么這不是主要考慮因素。

但是回想一下本文頂部的訂單處理示例。如果訂單在服務器中斷期間丟失,這可能意味着失去業務。(呃哦。)

考慮一下何時適合使用這些內存中的消息傳遞組件,以及何時將消息移交給外部消息代理(例如ActiveMQ )更合適,以確保可靠性。

沒有硬性規定。正確的解決方案始終取決於您的用例。因此,在使用 Camel 設計集成時,請考慮丟失消息時該怎么辦。會有關系嗎?如果是這樣,請考慮使用事務和持久消息傳遞來最大程度地減少任何消息丟失。

總結和最佳實踐

所以現在您已經了解了每個組件,您應該使用哪個,以及何時使用?

SEDA 與 Direct

  • 對於同一 CamelContext 中的同步(請求/響應)交互,請使用Direct

  • 對於同一 CamelContext 中的異步(即發即忘)處理(以類似隊列的方式處理消息),請使用SEDA

VM 與 Direct-VM:

  • 對於不同 CamelContext在同一個 JVM 中的**同步(請求/響應)交互,使用Direct-VM**

  • 對於不同 CamelContext在同一 JVM 中的**異步(即發即忘)交互,請使用VM**

Direct、SEDA、VM 和 Direct-VM 的比較

此表比較了每個組件,並顯示它們是否可以從另一個 CamelContext(在同一 JVM 中)訪問

Component 類型 來自同一個 CamelContext 來自另一個 CamelContext
Direct 同步 是的
Direct-VM 同步 是的 是的
SEDA 異步 是的
VM 異步 是的 是的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM