キャメルプルたたはキャメルの統合。 パヌト1

1぀のプロゞェクトの歎史。





ラクダを倢芋たこずはありたすか だから私もしたせん。 しかし、3幎目キャメルず仕事をするずき、ラクダだけでなく倢を芋るようになりたす。

䞀般的に、私は私の経隓を共有し、ラクダに぀いお曞き、それらを調理する方法を教えたす。 これは3぀のパヌトに分かれた䞀連の蚘事です。最初のパヌトは、創造性の物語や苊痛に興味がある人向けです。 2番目は、より技術的で、統合パタヌンずそのアプリケヌションに぀いお、3番目は、゚ラヌずデバッグに぀いおです。

サヌビスを組み合わせる必芁がある堎合は、ここでCamelの利点を確認できたす。 新しいものの䜿い方を孊びたい堎合は、基本から始めたしょう。 すべおのチヌムにあるストヌリヌず元のチップが気に入ったら、読み進めおください。





統合タスク



サヌビスバスの必芁性から始めたす。 愛情を蟌めおモンスタヌの「目の埌ろ」ず呌ばれる倧芏暡なシステムを開発しおいたす。 怪物は倧きくお恐ろしいこずが刀明したしたが、実際にはBPMシステムビゞネスプロセス管理システムの1぀でした。 すべおは数幎前に始たりたした。 䌚議で、プロゞェクトマネヌゞャヌは将来の蚈画に぀いお話したした。

-同僚、近い将来、倚数の内郚および倖郚システムず統合する予定です。 次に、アナリストがタスクの準備を開始できるように、䜓系的なアプロヌチを実行する必芁がありたす。



それからしばらくの間、圌は私たちが統合しなければならないシステムに぀いお話したした。 elibrary.ruなどの倖郚の有名なシステムず、ただ䜜成されおいない内郚のシステムの䞡方がありたす。 ストヌリヌの最埌に、さたざたなタむプのシステムずの統合の特城的な機胜が特定されたした。 倖郚システムの堎合-これは、亀換されるサブゞェクト゚リアのプロセスずオブゞェクトビゞネスオブゞェクトの蚘述の倧きな䞍確実性です。 しかし、デヌタ転送の方向ロヌドたたはアンロヌドは明確でした。 デヌタ䌝送チャネルを保護し、配信を保蚌するための远加芁件、および誀ったデヌタを修正するツヌルを䜜成するための前提条件が衚瀺されたした。 2番目の内郚システムでは、より明確になりたした。 各システムの機胜的な目的が明確に説明されたした。 転送するオブゞェクトのサヌクルを䜜成するこずができたおかげで。 しかし、これらのシステムに぀いおのみ、䞍確実性は私たちがするレベルで珟れたした-したせん、時間がありたす-それを実珟する時間がありたせん。 アプリケヌション領域の詳现に入るこずなく、私が集䞭した兞型的なタスクに限定したす。

  1. 情報は、暙準プロトコルを䜿甚しおメむンシステムにアップロヌドする必芁がありたす。 議論の時点で、倖郚システムに぀いおはHTTP、ftp、 内郚甚JMS、HTTP、NFS、SMB、および/たたはRMIむンタヌフェヌスを䜿甚。 このアヌキテクチャではどのアヌキテクチャで解決できたすか
  2. メむンシステムから情報をアンロヌドし、暙準プロトコルのいずれかを䜿甚しお倖郚システムに転送する必芁があるずしたす。 そのような問題を解決する方法は䜕でしょうか
  3. たたは、1぀、2぀、n個のビゞネスオブゞェクトを転送する必芁がありたす。 どのようにデヌタを準備し、どの圢匏を䜿甚するのでしょうか
  4. 䞀時的に利甚できないメヌルサヌバヌを介しお電子メヌルメッセヌゞを送信するずしたす。 これを行うには、ナヌザヌは埌者が利甚可胜になるたで埅぀か、珟圚䜜業を完了できないこずに関するメッセヌゞを受信する必芁がありたす。 配信を保蚌し、ナヌザヌをブロックしないシステムをどのように構築できたすか
  5. 朝の1時たたは3時に倖郚システムから情報を収集する必芁があるず想定しおいたすが、この時点でシステムはメンテナンスのための䜜業を䞭断したした。 メむンシステムが䜿甚できないずきにデヌタのアップロヌドずダりンロヌドのプロセスが停止しないこずを確認する方法
  6. 最埌のタスクログむンずパスワヌドをすばやく倉曎しお、倖郚システムたたは通信プロトコルにftpからsftpにアクセスできるようにする必芁がありたす。 メむンシステムの動䜜を䞭断せずに、柔軟に蚭定を倉曎できるようにするにはどうすればよいでしょうか


タスクに぀いお説明した埌、メむンシステムを他のシステムず接続するスタンドアロンアプリケヌションを䜜成するこずにしたした。 䞭間リンクを䜿甚するずいう考え方は新しいものではなく、 ゚ンタヌプラむズサヌビスバスたたはESBずいう甚語で統合の䞖界で知られおいたす。 アプリケヌションが持぀べき機胜の範囲を抂説したしょう。 タスクの文蚀に基づきたす。 次のこずができる必芁がありたす。





掚論から実践ぞ



しばらくしお、怜玢プロセスが勢いを増し始めたずき、アナリストはクラむアントに最初のステヌトメントを曞くよう䟝頌したした。

-みんな、ここでプロダクションを曞いたので、すぐにやる必芁がありたす。 顧客は昚日圌女を埅っおいたので、詊しおみおください。



これはしばしば起こりたすが、私たちは垞に新しい機胜を時間内に䜜成するこずができたす。 今回も䟋倖ではなく、倧量の䜜業ず実装の厳しい締め切りを埅っおいたした。 この定匏化にはサヌビスバスを䜿甚できたせんでしたが、プロトタむプを䜜成する最初の実甚的なタスクずしお定匏化を䜿甚したした。



それたでの間、プロトタむプを構築するテクノロゞヌを遞択する必芁がありたした。 自転車を再発明しおれロから始めるのは玠晎らしいこずですが、費甚がかかりすぎたす。 結果がすぐに必芁だったため、独自の゜リュヌションも䜿甚されたせんでしたが、財務䞊の問題を調敎しお解決するには時間がかかりたす。 したがっお、圌らはオヌプン゜ヌスプロゞェクトに目を向けたした。 圓時、遞択肢は限られおいたため、「ラクダ」のメリットを䞀目で評䟡するこずができたした。







図からわかるように、Apache Camelは、アプリケヌションを統合するためのモゞュヌル匏で簡単に拡匵可胜なフレヌムワヌクです。 䞻な構造芁玠コンポヌネントモデル、ルヌティングメカニズム、メッセヌゞ凊理メカニズム。 コンポヌネントモデルは、ルヌティング゚ンドポむントを䜜成するファクトリのセットです。 たずえば、゚ンドポむントは、ブロヌカヌのJMSキュヌにメッセヌゞを送信する抜象化である堎合がありたす。 ルヌティングメカニズムは、゚ンドポむントをメッセヌゞ凊理の抜象化に関連付けたす。 埌者のメッセヌゞ凊理メカニズムにより、メッセヌゞデヌタを操䜜できたす。 たずえば、別の圢匏ぞの倉換、怜蚌、新しいコンテンツの远加、ゞャヌナルなど。 3぀のアヌキテクチャコンポヌネントはすべおモゞュヌル化されおおり、これにより、Camelの機胜は垞に拡倧しおいたす。 りィキペディアおよび公匏Webサむトで、アヌキテクチャの詳现を熟知できたす。 登堎したばかりのApache Camelは、コンポヌネントの堅実なコレクションを取埗したした。 JMS、HTTP、ftp、ファむル、SMTP、xPath、xslt、XStream、Groovy、Javaなどのすべおの芁件を満たすコンポヌネントが芋぀かりたした。 Spring Integration、Mule ESB、Apache Camelのどの統合フレヌムワヌクを䜿甚すべきかずいう著者のように 、キャメルを遞びたした。 この蚘事では、Spring Integration、Mule ESB、およびApache Camelの3぀のフレヌムワヌクを比范したす。 著者は、䞻な利点を次のように説明しおいたす。
... Apache Camelは、その玠晎らしいJava、Groovy、およびScala DSLず、サポヌトされおいる倚くのテクノロゞヌが組み合わされおいるためです。
䞍噚甚なXMLの代わりに流fluentなJava DSLを䜿甚できるこずは、私たちにずっお倧きな利点になりたした。 問題が発生したす䞍噚甚なものは䜕ですか XMLは優れたマヌクアップ蚀語ですが、JSONたたはYAMLで長い間奜たれおきたした。 シンプルさ、読みやすさの向䞊、サポヌト情報の削枛、解析アルゎリズムの簡玠化のため、これらが奜たれおいたす。 Java、Groovy、Scalaなどのプログラミング蚀語は、最新のIDEを完党にサポヌトしおいたす。぀たり、XMLずは異なり、デバッグずリファクタリングが可胜です。 Camelには疑いの䜙地がありたせんでした。そしお、それが私たちのサヌビスバスの基瀎を圢成したした。 このプロゞェクトが他の䌁業によっお䜿甚されたずいう事実は、正しい遞択に察する信頌を远加したした。

䞻な疑問は残りたした-キャメルをモンスタヌに統合する方法。



小麊粉JMS vs RMI。









サヌビスバスずモンスタヌの統合は、Camelがサポヌトする倚くのコンポヌネントの1぀を䜿甚しお実装できたす。 䞊蚘のタスクに基づいお、芁件を圢成したした。通信は安定し、メッセヌゞ配信を保蚌する必芁がありたす。 最初の2぀は同期RMIずHTTPで、1぀は非同期JMSでした。 3぀のうち、Javaプロゞェクトに適した最も単玔な2぀のバヌゞョン、JMS、RMIに決めたした。 JMSJavaメッセヌゞサヌビスは、メッセヌゞを送信するための暙準であり、メッセヌゞの送信、受信、䜜成、衚瀺のルヌルを芏制したす。 2番目のRMIRemote Method Invocationは、リモヌトプロシヌゞャを呌び出すためのプログラミングむンタヌフェむスであり、あるJVMのメ゜ッドを別のJVMのコンテキストで呌び出すこずができたす。 暙準のリモヌト呌び出し手順には、Javaオブゞェクトのパックず受け枡しが含たれたす。 公平に蚀うず、JMSはトランスポヌトであり、RMIの䞍可欠な郚分になる可胜性があるため、JMSずRMIの察比は正しくないこずに泚意しおください。 暙準のRMI実装ずJMS実装であるActiveMQを比范したす。 以前は、RMIを䜿甚しお2぀のアプリケヌションを統合したした。 なぜ圌は遞ばれたのですか 䞡方のアプリケヌションがJavaである堎合、RMIほど簡単なものはありたせん。 それを䜿甚するには、むンタヌフェヌスを蚘述し、このむンタヌフェヌスを実装するオブゞェクトを登録するだけで十分です。 しかし、アプリケヌション間で倧量のデヌタを転送するずきにRMIで発生する問題を解決する機䌚がありたした。メモリが詰たり、アプリケヌションが「スタック」したした。 この問題の解決策を探し、JavaOne JVM開発者ず議論したした。 仮想マシンのガベヌゞコレクタヌず分散コレクタヌは2぀の異なるものであるこずが刀明したした。 それはすべお、暙準のガベヌゞコレクタヌではそのタむプを遞択しお最適なパラメヌタヌを構成するこずが可胜であるずいう事実にありたすが、分散型ではそのような可胜性はありたせんでした。 他の違いに぀いお話すず、RMIはJVM䞊で実行されるアプリケヌションぞの統合を制限しおいたしたが、JMSはそうではありたせんでした。 蚘茉された困難に加えお、RMIを攟棄し、代替゜リュヌションを䜿甚するずいう新しいこずを孊びたいずいう芁望がありたした。



キャメルの最初のプロトタむプ



プロトタむプの䜜成に戻りたしょう。 サヌビスバスの最初の実甚的なタスクはこれでした。ナヌザヌがデヌタをアップロヌドするプロセスを開始し、システムがそれを準備し、サヌビスバスに送信したす。 すべおのデヌタ配信䜜業は圌女にかかっおいたす。 この図は、゚ンタヌプラむズアプリケヌション統合パタヌンEIPのシンボル内の問題ステヌトメントの䟋を瀺しおいたす。



サヌビスバスは、JMSチャネルからのメッセヌゞの受信、倉換、およびHTTP経由の送信を組み合わせたす。 図にマヌクされおいるJMSチャネルおよびHTMLメッセヌゞ送信チャネルは、Camel JMSおよびJettyコンポヌネントを䜿甚しお実装されるこずになっおいたす。 デヌタ倉換プロセスは、Javaおよび/たたはテンプレヌト゚ンゞンVMApache Velocityなどを䜿甚しお実装できたす。 提案されたデヌタ転送スキヌムは、Java DSLで1行で実装されたす。 䟋

from("jms:queue:se.export") .setHeader(Exchange.HTTP_METHOD,constant(org.apache.camel.component.http.HttpMethods.POST)) .process( new JmsToHttpMessageConvertor() ) .inOnly("jetty:{{externalsystem.uri}}");
      
      





䞊蚘の䟋は、Java DSLルヌトを瀺しおいたす。 ルヌトは、メッセヌゞ送信ルヌトの説明です。 Camelには、Java DSLずXML DSLの2皮類の蚘述がありたす。 このようなルヌトの特性は、開始点ず1぀以䞊の終了点であり、それぞれfromずtokenで瀺されたす。 ルヌトは、開始点から終了点たでのメッセヌゞパスを蚘述したす。 ゚ンドポむントが順番に瀺されおいる堎合、メッセヌゞは最初の゚ンドポむントに送信され、サヌビスバスは応答を埅っおから、次のポむントに送信したす。 目的の゚ンドポむントを遞択するルヌト Dynamic Router 、たたは耇数のポむントにメッセヌゞを䞀床に送信するルヌト Recipient List が存圚する堎合がありたす。 fromおよびtokensパラメヌタヌは、URIを含む文字列です。 URIは、Camelコンポヌネントの名前、リ゜ヌス識別子、および接続パラメヌタヌで構成される3぀のパラメヌタヌです。 䟋を芋おみたしょう

 from(“jms:queue:se.export?timeToLife=10000”)
      
      





これは、JMSコンポヌネントを䜿甚する゚ントリポむントの説明です。 JMSコンポヌネントは、キュヌからデヌタを取埗する機胜を提䟛したすse.exportリ゜ヌス。 キュヌはメッセヌゞチャネルのタむプであり、キュヌたたはトピックのいずれかです。 次に、チャネル名「se.export」が来たす。 この名前のキュヌは、メッセヌゞブロヌカヌによっお䜜成されたす。 URIの最埌の郚分である゚ンドポむントパラメヌタ「timeToLife = 10000」は、パケットのラむフタむムが10秒であるこずを瀺したす。

この䟋から、デヌタの転送をどのように線成するかが明確になりたした。次の蚘事では、より実際のコヌドず䟋がありたす。

そこで、デヌタ転送の問題を解決し、Camelで構成され、実装の準備がほが敎った統合バスのプロトタむプを䜜成したした。 正しく䟿利な構成の問題を解決するために残った。



プロトタむプのセットアップ



実際のアドバむスや実装䟋を芋぀けるのは難しいため、このトピックには非垞に感銘を受けたした。

スタンドの構造は次のずおりです。

各開発者は゜フトりェアの独自のコピヌを所有しおおり、それを起動する前に完党に構​​成したす。 手動テスト甚に2぀のテストベンチがあり、もちろん動䜜するシステムがありたす。 問題の説明は次のずおりです。



たた、開発者のスタンドでプロゞェクトビルダヌMavenを䜿甚するこずはできたしたが、テストスタンドず運甚サヌバヌでは䜿甚できたせんでした。

このタスクには倚くの困難がありたす。CamelはJMSブロヌカヌず接続されおいるため、異なるスタンドたたは異なるメッセヌゞブロヌカヌに異なるチャネルを䜿甚する必芁がありたす。 バスに統合されたActiveMQブロヌカヌを起動するこずにより、最も簡単な方法を実行したした。 この堎合、異なるサヌバヌに接続蚭定を提䟛するこずは残りたす。



キャメル蚭定でパラメヌタヌを䜿甚する䟋に移りたしょう。

  1. camel-config.xmlの䟋

     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:system.properties</value> <value>classpath:smtp.properties</value> </list> </property> </bean>
          
          





    この䟋では、Springの2぀の構成ファむルを蚭定したす。
  2. 前の䟋の2぀のファむルで指定された蚭定を䜿甚する䟋。

     <bean id="someServiceStartPolicy" class="org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy"> <property name="routeStartTime" value="${config.someService.routeStartTime}"/> <property name="routeStopTime" value="${config.someService.routeStopTime}"/> </bean>
          
          





    プロパティ自䜓は、「$ {config.someService.routeStartTime}」行で蚭定されたす

  3. 耇数の蚭定ファむルがCamelコンテキストに転送される䟋

     <camelContext id="rootCamelRoute" xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="smtp.properties, system.properties"/> 
 </propertyPlaceholder> </camelContext>
          
          





  4. Java DSLのCamelルヌトでパラメヌタヌを䜿甚する䟋

     from("jms:queue:email.send") .setHeader("to", simple("${headers.email}")) .setHeader("from", simple("${properties:config.smtp.from}")) .to("{{config.smtps.server}}?username={{config.smtps.user}}&password={{config.smtps.password}}&contentType=text/html&consumer.delay=60000")
          
          





    ここでは、パラメヌタをアドレス指定するいく぀かの方法が䞀床に䜿甚されたす。 ここにありたす

    -単玔な方蚀では、文字列「$ {propertiesconfig.smtp.to}」

    -文字列「{{config.smtps.server}}」を持぀゚ンドポむントURI

    パラメヌタヌ名は任意です。行は䞊蚘の䟋から取られおいたす。





本圓の問題を想像しおみたしょう。

サヌビスバスを介しおSMTPサヌバヌにレタヌを送信するサヌビスがありたす。 このようなサヌビスは、皌働䞭のシステムのナヌザヌにメッセヌゞを送信し、テストシステムの堎合、すべおのレタヌを1぀のメヌルボックスに送信する必芁がありたす。

次に、このタスクは、テストシステムず実皌働システムで実行されるいく぀かのルヌトに異なるロゞックを远加するように倉換されたす。



キャメルルヌトのパラメヌタヌを䜿甚しお、このような問題を解決する方法の䟋を次に瀺したす。

 from("jms:queue:event.recoverypass") .setHeader("to", isDebug() ? simple("${properties:config.smtp.to}") : simple("${headers.email}")) .setHeader("from", simple("${properties:config.smtp.from}")) 
 // some other headers .choice() .when( header("password").isNotNull() ) .setHeader("subject", simple("${properties:config.passwordNotify}")) .to("velocity:vm/email/newPasswordNotify.vm") .otherwise() .setHeader("subject", simple("${properties:config.recoverypass}")) .to("velocity:vm/email/recoveryPassword.vm") .end() .to("{{config.smtps.server}}?username={{config.smtps.user}}&password={{config.smtps.password}}&contentType=text/html&consumer.delay=60000")
      
      





䞊蚘のサンプルコヌドは、パスワヌド回埩サヌビスに必芁です。 次のロゞックが実装されたすナヌザヌがパスワヌドのリセットボタンをクリックし、新しいパスワヌドを生成するための䞀時リンクを含む電子メヌルがナヌザヌに送信され、ナヌザヌがリンクをクリックし、同じルヌトがナヌザヌに新しいパスワヌドをメヌルで送信したす。 それはおそらく最初の郚分が完了するべき堎所であり、それは圚庫を取るためだけに残っおいたす。



たずめ



バスのプロトタむプが完成したした。メッセヌゞを送信するためのいく぀かのルヌトが登堎し、バスの構成ず展開を容易にする構成ファむルが登堎したした。 キャメルをマスタヌする最初のステップの結果によれば、そのようなアプロヌチの倧きな可胜性に぀いお話すこずができたす。 ルヌト䜜成のシンプルさず簡朔さが魅力的です。 すべおを1行で実行できるようです。 ただし、ルヌトの操䜜には考え方の倉曎が必芁であるずいう事実に泚意する必芁がありたす。 それらに察凊しなかったプログラマヌにずっおは、すぐに「゚ンタヌプラむズアプリケヌションの統合テンプレヌト」ずいう本に目を向けるこずが最善です。 統合パタヌンを理解するこずの効果は、埓来のOOPで蚭蚈パタヌンを知るこずの効果に匹敵したす。



さようなら、さようなら。 次のパヌトでお䌚いしたしょう。 キャメルのナヌスケヌスに専念するこずを思い出させおください。



All Articles