日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

发掘Apache Camel的力量

發(fā)布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 发掘Apache Camel的力量 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近幾年,ESB軟件越來越受歡迎。 如果大多數(shù)人通常知道什么是ESB,那么他們很少會清楚地了解這種體系結(jié)構(gòu)的不同組件的確切作用。

例如,Apache ServiceMix由三個主要組件組成:Apache Karaf(OSGI容器),Apache ActiveMQ(消息代理)和Apache Camel。 順便問一下,駱駝到底是什么? 什么是“ routing and mediation engine ”? 有什么用?

我已經(jīng)與Camel合作了大約一年,我認(rèn)為-盡管根本不是Camel專家,但我現(xiàn)在有足夠的后見之明,可以使用一些非常具體的示例讓您發(fā)現(xiàn)Camel的興趣和力量。為了清楚起見,在本文的其余部分中,我將使用Spring DSL –假設(shè)讀者熟悉Spring語法。

用例

讓我們想象一下,我們想使用Camel實現(xiàn)以下場景。 產(chǎn)品信息請求將以平面文件(CSV格式)的形式發(fā)送到特定文件夾中。 該文件的每一行都包含特定客戶關(guān)于特定汽車型號的單個請求。 我們希望向這些客戶發(fā)送有關(guān)他們感興趣的汽車的電子郵件。為此,我們首先需要調(diào)用Web服務(wù)以獲取其他客戶數(shù)據(jù)(例如,他們的電子郵件)。 然后,我們必須從數(shù)據(jù)庫中獲取汽車特性(讓我們說一個文本)。 由于我們希望郵件看起來像樣(例如HTML),因此也需要進(jìn)行小的文本轉(zhuǎn)換。

當(dāng)然,我們不希望僅對請求進(jìn)行順序處理,而是希望引入一些并行性。 同樣,我們也不想多次將完全相同的郵件發(fā)送給不同的客戶(而是將相同的唯一郵件發(fā)送給多個收件人)。 利用我們后端的集群功能來平衡對Web服務(wù)的調(diào)用也將是一件很不錯的事情。 最后,在處理請求失敗的情況下,我們希望以某種方式跟蹤原始請求,以便例如可以通過郵政發(fā)送。
一個(可能的)駱駝實現(xiàn):

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://camel.apache.org/schema/springhttp://camel.apache.org/schema/spring/camel-spring.xsd " ><camelContext xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="myDLQ"><!-- 2 redeliveries max before failed message is placed into a DLQ --><errorHandler id="myDLQ" type="DeadLetterChannel" deadLetterUri="activemq:queue:errors" useOriginalMessage="true"><redeliveryPolicy maximumRedeliveries="2"/></errorHandler><!-- The polling of a specific folder every 30 sec --><route id="route1"><from uri="file:///Users/bli/folderToPoll?delay=30000&delete=true"/><unmarshal><csv/></unmarshal><split><simple>${body}</simple><setHeader headerName="customerId"><simple>${body[1]}</simple></setHeader><setHeader headerName="carModelId"><simple>${body[2]}</simple></setHeader><setBody><simple>${body[0]}</simple></setBody><to uri="activemq:queue:individualRequests?disableReplyTo=true"/></split></route><!-- The consumption of individual (jms) mailing requests --><route id="route2"><from uri="activemq:queue:individualRequests?maxConcurrentConsumers=5"/><pipeline><to uri="direct:getCustomerEmail"/><to uri="direct:sendMail"/></pipeline></route><!-- Obtain customer email by parsing the XML response of a REST web service --><route id="route3"><from uri="direct:getCustomerEmail"/><setBody><constant/></setBody><loadBalance><roundRobin/><to uri="http://backend1.mycompany.com/ws/customers?id={customerId}&authMethod=Basic&authUsername=geek&authPassword=secret"/><to uri="http://backend2.mycompany.com/ws/customers?id={customerId}&authMethod=Basic&authUsername=geek&authPassword=secret"/></loadBalance><setBody><xpath resultType="java.lang.String">/customer/general/email</xpath></setBody></route><!-- Group individual sendings by car model --><route id="route4"><from uri="direct:sendMail"/><aggregate strategyRef="myAggregator" completionSize="10"><correlationExpression><simple>header.carModelId</simple></correlationExpression><completionTimeout><constant>60000</constant></completionTimeout><setHeader headerName="recipients"><simple>${body}</simple></setHeader><pipeline><to uri="direct:prepareMail"/><to uri="direct:sendMailToMany"/></pipeline></aggregate></route><!-- Prepare the mail content --><route id="route5"><from uri="direct:prepareMail"/><setBody><simple>header.carModelId</simple></setBody><pipeline><to uri="sql:SELECT xml_text FROM template WHERE template_id =# ?dataSourceRef=myDS"/><to uri="xslt:META-INF/xsl/email-formatter.xsl"/></pipeline></route><!-- Send a mail to multiple recipients --><route id="route6"><from uri="direct:sendMailToMany"/><to uri="smtp://mail.mycompany.com:25?username=geek&password=secret&from=no-reply@mycompany.com&to={recipients}&subject=Your request&contentType=text/html"/><log message="Mail ${body} successfully sent to ${headers.recipients}"/></route></camelContext><!-- Pure Spring beans referenced in the various Camel routes --><!-- The ActiveMQ broker --><bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"><property name="brokerURL" value="tcp://localhost:61616"/></bean><!-- A datasource to our database --><bean id="myDS" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="org.h2.Driver"/><property name="url" value="jdbc:h2:file:/Users/bli/db/MyDatabase;AUTO_SERVER=TRUE;TRACE_LEVEL_FILE=0"/><property name="username" value="sa"/><property name="password" value="sa"/></bean><!-- An aggregator implementation --><bean id="myAggregator" class="com.mycompany.camel.ConcatBody"/></beans>

和(僅!)Java類的代碼:

public class ConcatBody implements AggregationStrategy {public static final String SEPARATOR = ", ";public Exchange aggregate(Exchange aggregate, Exchange newExchange) {if (aggregate == null) {// The aggregation for the very exchange item is the exchange itselfreturn newExchange;} else {// Otherwise, we augment the body of current aggregate with new incoming exchangeString originalBody = aggregate.getIn().getBody(String.class);String bodyToAdd = newExchange.getIn().getBody(String.class);aggregate.getIn().setBody(originalBody + SEPARATOR + bodyToAdd);return aggregate;} }}

一些解釋

  • route1 ”處理傳入的平面文件。 文件內(nèi)容首先被解組(使用CSV格式),然后分成行/記錄。 每行都將變成一個單獨(dú)的通知,該通知將發(fā)送到JMS隊列。
  • route2 ”正在使用這些通知。 基本上,完成一個請求意味著依次執(zhí)行兩件事(“管道”):獲取客戶電子郵件(route3)并向他發(fā)送郵件(route4)。 請注意“ maxConcurrentConsumers”參數(shù),該參數(shù)用于輕松滿足我們的并行性要求。
  • route3 ”對如何獲取客戶電子郵件進(jìn)行建模:只需通過解析(使用XPath)在兩個后端節(jié)點(diǎn)上可用的(安全的)REST Web服務(wù)的XML響應(yīng)即可。
  • route4 ”包含發(fā)送大量郵件的邏輯。 每次收集到10個類似的發(fā)送請求(在我們的示例中,是對同一輛汽車的10個請求)(并且我們不準(zhǔn)備等待超過1分鐘),我們希望整個過程以新消息繼續(xù)進(jìn)行(或“駱駝?wù)Z”中的“交換”是10條組合消息的串聯(lián)。 繼續(xù)該過程意味著:首先準(zhǔn)備郵件正文(路由5),然后將其發(fā)送到組(路由6)。
  • 在“ route5 ”中,發(fā)出SQL查詢,以便根據(jù)汽車型號獲得適當(dāng)?shù)奈谋尽?在該結(jié)果上,我們應(yīng)用了一個小的XSL-T轉(zhuǎn)換(它將用xsl轉(zhuǎn)換的輸出替換當(dāng)前交換主體)。
  • 當(dāng)輸入“ route6 ”時,交換包含我們所需的一切。 我們有收件人列表(作為標(biāo)頭),也有(正文中)要發(fā)送的html文本。 因此,我們現(xiàn)在可以繼續(xù)使用SMTP協(xié)議進(jìn)行實際發(fā)送。
  • 如果出現(xiàn)錯誤(例如臨時網(wǎng)絡(luò)問題)–在整個過程中的任何地方,Camel都會在放棄之前最多進(jìn)行兩次其他嘗試。 在后一種情況下,始發(fā)消息將由Camel自動放置到JMS死信隊列中。

結(jié)論

駱駝確實是一個很棒的框架–并不完美,但仍然很棒。 您會驚訝地看到,只需幾行代碼即可對復(fù)雜的場景或路線進(jìn)行建模。 您也可能很高興看到您的代碼多么清晰,同事們能夠多快地理解您的路線邏輯。

但這當(dāng)然不是主要優(yōu)勢。 使用Camel主要是邀請您考慮企業(yè)集成模式(又稱“ EIP”); 它可以幫助您使用眾所周知的成熟技術(shù)將原始復(fù)雜性分解為不太復(fù)雜(可能是并發(fā))的子路由,從而實現(xiàn)更模塊化,更靈活的實現(xiàn)。 特別是,使用去耦技術(shù)可以簡化解決方案中單個零件或組件的替換或重構(gòu)。

參考:從我們的W4G合作伙伴 Bernard Ligny中 發(fā)現(xiàn)Apache Camel的功能 。

翻譯自: https://www.javacodegeeks.com/2012/12/discovering-the-power-of-apache-camel.html

總結(jié)

以上是生活随笔為你收集整理的发掘Apache Camel的力量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。