天の月

ソフトウェア開発をしていく上での悩み, 考えたこと, 学びを書いてきます(たまに関係ない雑記も)

実践!インテグレーションパターンに参加してきた

modeling-how-to-learn.connpass.com

こちらのイベントに参加してきたので、会の様子と感想を書いていきます。

会の概要

以下、connpassのイベントページから引用です。

ファウラーの名著『エンタープライズアプリケーションアーキテクチャパターン』(通称PofEAA)を受けて2003年に登場した2つの重要な技術書が『ドメイン駆動設計』(DDD)と『エンタープライズインテグレーションパターン』(EIP)でした。しかし、DDDが邦訳も出版されてかなり受け入れられているのに比べ、双子の片割れであるEIPは邦訳もまだ出版されずいまだに不遇をかこっています。

とはいえApache KafkaやJMS、AMQP、MQTTといったメッセージングミドルウェアプロトコル、またApache Camel、AkkaといったEIPを実装したフレームワークも充実してきていて、それらを通してEIPを実践している人も少なからずいます。

発表では、EIPとはなんぞやというところから始めて、EIPの紹介、アプリケーションアーキテクチャの中でのEIPの位置付け、Apache Camelを使ってどうやってEIPを実現できるか、といったところを話します。時間があればApache Camelの最新の取り組みも紹介したいです。

会の様子

実践EIP入門 ― Apache CamelでEIPを使いこなす~佐藤匡剛さん Red Hatシニアソフトウェアエンジニア~

最初にEIP初心者のために、EIPの基本知識やパターンの紹介をしてくれました。
その後、Apache Camelを使用したデモや実際に佐藤さんが取り組んでいるPJで開発している内容のデモを実際にしてくれるという構成でした。

EIPの基本知識やパターン

インテグレーションの基本パターンの中から、EIPの肝となるメッセージングのデザインパターンを簡単かつ分かりやすく説明をしてくれました。*1

まず、EIPのメリットとして、リアクティブなこと, コード作成やコードを疎結合にする際にコード上だけでなく時間的結合も削除できること, 業務モデルを自然にできることが紹介されていました。

その後、メッセージングのパターン*2として、6つのパターン(メッセージングチャネル/メッセージ生成/メッセージルーティング/メッセージングエンドポイント/メッセージ変換/システム管理)について駆け足ではありますが説明をしてくれました。

最後に、Apache Camelを使用したデモや実際に佐藤さんが取り組んでいるPJで開発している内容のデモをしてくれました。
Apache Camelを使用したデモでは、今回のイベントのハッシュタグtweetされている内容を収集したり今日の東京の天気を確認するデモをしてくれて、その後に佐藤さんが取り組んでいるPJであるApache Camel K*3のデモを見せてもらいました。

導入の発表でEIPを分かりやすく整理してくれてありがたい時間でしたし、EIPのパターン説明の中で出てきた多数の例えがどれも分かりやすく、頭にすっきりと入ってきました。

EIPとAkkaについて~かとじゅんさん Chatworkテックリード

TCPやHTTPといった一般的なメッセージ配送における問題点としてメッセージロストの問題*4を紹介し、そういったメッセージロストの問題に対処するための「配送保証」の考え方をAkkaで説明してくれました。

最初に、メッセージロストの問題を「二人の将軍問題」のアナロジーで解説してくれました。どんなに多くrequest/replyしても、受信者と送信者で100%合意には決して至らないというお話でした。
また、メッセージ配送の信頼性という観点から、信頼性が低い(ただしパフォーマンスが高くコストが低い)ものから順に以下3方式を解説してくれました。

  • At-most-once delivery(メッセージは0 or 1回配送され、相手に届かないことがある。askで応答確認は可能だが、タイムアウト考慮の処理などはしない)
  • At-least-once delivery(メッセージは最低1回は配送される。複数回メッセージを送った場合はメッセージが重複する可能性がある。送信側にはディスクが必要。)
  • Exactly-once delivery(メッセージは正確に一回だけ配信される。受信側にもディスクが必要。)

次に、今回の発表の核となる「配送保証」の考え方について説明がありました。
「配送保証」はメッセージングシステムがデータストアにメッセージを保存し、メッセージが正常に送信されたことが確認できればメッセージが削除される*5パターンだということで、これを具体的にコードレベルで解説するとどうなるのか?というのをAkkaのソースコードサンプルで丁寧に(そして時々突っ込みを入れながら)解説してくれました。

抽象的なアナロジーや思想的な話から、具体的なコードの実例までを見せてもらえた上に、コードの解説はテストコードからめちゃくちゃ丁寧に話をしてくれたので、わくわくするような発表でした。

アプリケーションクラスの設計パターンとしてのEIP~増田さん (有)システム設計 代表~

最後の発表として、増田さんから現場の設計パターンにどうEIPが適用できるのか、という話をしてくれました。
増田さんは純粋なメッセージングの仕組みを考えるためにEIPを利用する機会はそこまでないということですが、複雑なドメインで設計する際に、EIPの考え方を良く使用されているということです。具体的なパターンとしては、以下のようなものが挙がっていました。

  • 並列化(一つのクラスに役割を詰め込み過ぎないようにプロセスマネージャー的な役割と機能特化のクラス群を置く)
  • 直列化(段階ごとに別のクラスが直列に処理をする。void型で副作用があることを明示し、処理が中断した場合は例外を発生させる)
  • 分岐(ルーターが分岐役を担い、適切な処理役に処理を任せる)
  • ソース→分割→振り分け→個別処理→集約(EIPでいうスプリッターやルーターで処理を最初に分割して処理を振り分けして、アグリゲーターで最後に結果を集約する)
  • エンリッチ(エンリッチャーが必要な情報を付加して後続処理に渡すことで、データの前準備を分離する)
  • フィルター(重い情報が詰め込まれた時、不要情報を取り除いたうえで後続処理には必要な情報のみ渡す)
  • 荷物を預かり引換券を渡す(大きな情報はデータベースに渡し、キーだけを渡すことで、データを単純化する)
  • データ形式の正規化(形式が不ぞろいのデータを共通の形式に変換して後続処理に渡す)

ディスカッション

最後にディスカッションがありました。
が、今回はプライベートの都合でディスカッションには参加できませんでした。。。毎回ディスカッションを一番楽しみにしているため、残念です。

全体を通した感想

EIPの基本的な話の復習に加えて、実際に実装レベルでEIPに踏み込んだ話を聴くこともできて満足でした!

また、メッセージング以外の設計パターンにもEIPの考え方を利用することができる、という考え方も面白く、勉強になることが多い会でした。

*1:メッセージングの導入はメッセージングブローカーをはじめとしたミドルウェアの導入が必要なので敷居が中々高かったものの、k8sやDockerの普及に伴い、簡単に環境構築できる環境が揃いつつあるというお話でした

*2:ここでいうパターンはGoFデザインパターンのようにオチだけが表現されているものではなく、ソフトウェア開発のストーリーの上から下までをカバーするアレグザンダーのパターンランゲージ的な意味合いを持っているというお話でした

*3:Kはkubernetes / KnativeのK

*4:これは高パフォーマンス低コストを実現しているが故のもの

*5:メッセージが保存されるまでは送信操作は完了しない