たなかこういちの資料室

システム開発に携わる筆者があれこれ試したことや学んだことについてのまとめ

Vert.xとRxJavaについて、メモ

◆注意◆
本記事の内容は2015年8月頃にまとめたものです。最新の状況は変化している可能性があります。
 
Vert.xとは?
 
位置付け
JVM上で動く、非同期、ノン・ブロッキング、イベント駆動なサーバー・アプリケーション・フレームワークです。TomcatなどのServlet Engineに対して競合となります。
ScalaClojureなどJava以外のJVM言語向けAPIも用意されています。
・よく「Node.jsのJVM版」と表現されることがあります。Node.jsより速いとされています。
・Vert.xのCoreの足回りにはNettyが使われています。NettyとVert.xの開発者は連携して開発を進めているようです。
 
構造や機能
・「Verticle」という一つのイベントループを持つスレッドがあり、これがVert.xの内部的な実行単位となります。Vert.xは、複数のVerticleを“起動”するとき、一つのVerticleを一つのCPUコアに割り当てるように動作します。
・複数の異なるVerticleは、「Event Bus」を介してメッセージパッシングで連携します。この連携はアクターモデルとして捉えることができます。
・また、「Event Bus」の足回りにはHazelcastという分散クラスターを実現するミドルウエアが用いられています。これにより、「Event Bus」で繋がる複数の「Verticle」をマルチマシンに展開させることもできます。
・ただし、Eventは永続化されないので、プロセスが落ちたら消失することに注意。
・DBアクセスのような長時間かかる処理を実行する場合、「Worker Verticle」を立ててforkさせ、Worker側で実行させることができます。そうしてメインのイベントループがブロックしてしまうことを避けます。
・RxJavaサポート、さらにJava8ラムダ式を用いることで、Event Busハンドラーの記述がスマートになります。(※いわゆる"callback hell"を回避できる。)
 
Vert.x参考記事
 
こちらのブログの連載がよく書かれています。先達に感謝です。「第1回」の記事冒頭で紹介されているリンク先もそれぞれ読みましょう。
 
KenichiroMurata氏、「Taste of Tech Topics」より、「Vert.x がいいね!(第1回:入門する)」:
 
次は、株式会社DMM.comラボにおけるVert.x導入事例の連載記事となります。まさに私のような“Tomcatあがり”な人に分かりやすい内容になっています。
 
CodeZineより、「Javaプログラマーのための実践「Vert.x」」(※連載記事一覧):
 
Vert.x with RxJava
 
Vert.xにはRxJavaサポートがあります。これを用いると、Vert.xのEvent Busとハンドラーを、RxJavaのObservable/Observerとして記述できるようになります。
 
<参考記事>
KenichiroMurata氏、「Taste of Tech Topics」より、「RxJavaを使ってCallback Hellから脱出する( Java8 ラムダ編 )」:
 
RxJavaとは?
 
歴史
Microsoft社が.NET向け「Reactive Extensions」を開発し、2012年にOSSとして公開しました。
・それをNetflix社がJavaへ移植、自社システムをRxJavaベースのものへ全面書き換えしました。その事例発表が2013年に行われました。
・このNetflix社の成功事例を受けて、「Reactive」が急速普及しました。
・2015年8月時点で「Reactive Extensions」は下記言語に移植されています。
 
.NET, Java, JavaScript, Scala, Clojure, C++, Ruby, Python, Groovy, Swift, etc.
 
機能
・一連の一塊のデータ処理があるとき、その処理の各ステップを部分処理に分割して、各部分処理を可能なところで並行に実行することで、元の一連の処理のトータルの実行時間の短縮を図ることが目的です。
・そのために、(1) 一塊の処理を部分処理に分割して再合成するときの、その分割・再合成パターンを一揃え準備、(2) そのパターンを一つの統一されたI/Fの元で自在に組み合わせ可能とする具体的なプログラミング上の方式を考案、それを「Observable」として実装しました。
 
■ RxJava参考記事
 
RxJavaやReactive Extensionsの概要説明は幾らでもあります。それらを並べておきます。
 
ReactiveX(※本家サイト)、"Introdution":
 
@okapies氏、「関数型プログラマのためのRx入門(前編)」:
 
マルレク、2013年1月21日、開催テーマ「Reactiveプログラミング」、講演資料(※45枚目より):
 
Ben Christensen氏(※Netflix社エンジニア)、JavaOne 2013講演資料、"Functional Reactive Programming with RxJava":
 
Ben Christensen氏、GOTO Chicago 2015講演資料、"Applying Reactive Programming with RxJava":
 
Yoshifumi Kawai氏、「Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方」:
 
考察(Vert.xとRxJavaの対比)
 
Vert.xは、「非同期、並行」、「ノン・ブロッキング」、「イベント駆動」をキーワードとする、サーバー・アプリケーション・フレームワークです。RxJavaも「非同期、並行」、「イベント駆動」がキーワードとされるミドルウェアです。両者とも、非同期、並行、、といった機構を、ハイパフォーマンス実現のために用いようとしています。両者はほとんど類似の機能性をもったライブラリに思えました。
 
しかし参考資料を子細に検討していくと両者の基本的な差異が理解できました。それを以下に記しておきます。
 
Vert.xはサーバー構築用フレームワーク、RxJavaにはサーバー構築用機構は無い
 
Vert.xの第一義的な特徴は、Verticleという常駐スレッドが存在することでしょう。RxJavaの方は、Vert.xにおけるWorkerに相当するようなスレッドforkのメカニズムは内包していますが、フロント側でlistenしつつ常駐するスレッドのための機構は提供されていません。やはり、Vert.xはサーバー構築向けフレームワークであり、RxJavaはそうでは無い、ということになるでしょう。
 
Vert.xは単位時間当たりに受け付け可能なリクエスト数を増やすことが目的、RxJavaは一つの処理の実行時間を短縮することが目的
 
Vert.xにおける非同期、並行とは、あくまでもシングルスレッドなイベント・ループをブロックさせないためにある、と言い切ってよいです。イベント・ループをブロックしないようにするのは、もっぱら単位時間当たりに受け付けることのできるリクエスト数を稼ぐためです。その一方、Wokerに委譲されたある特定の一つのリクエストに対応した処理の実行時間がどれほど長いかあるいは短いかについては、Vert.xのアーキテクチャーとしてはあまり関心がないです。少なくとも処理時間の長いリクエストが存在するとき、処理時間の短いリクエストがその巻き添えをくらうことが無いようにしています。
 
RxJavaの関心点は全く逆で、特定の一つの処理の実行時間を如何に短縮するかが目的となっていると言えます。処理実行時間短縮の戦略は、一つの一連の処理を幾つかの部分処理に分割し、各部分処理を可能なところで並行に実行しよう、というものです。一連の処理を部分処理に分割し後に再合成する機構のために、つまり"Composability"のために、Functional Programingの道具を総動員しています。
 
Vert.xはスループット向上が目的、RxJavaはレイテンシー改善が目的、とまとめることができるでしょうか。
 
◆以上