RxJavaチームは18ヶ月の開発サイクルを経て彼らのリアクティブJavaフレームワークのバージョン2.0をリリースした。このリリースは重要なマイルストーンをもたらす。RxJavaはReactiveXファミリーのライブラリとフレームワークの一部である。これは彼らの言葉では"オブザーバパターンとイテレータパターン、関数型プログラミングからのもっともよいアイデアの組み合わせである"。プロジェクトの"2.0では何が違うのか"はすでにRxJava 1.xに親しんでいる開発者にとってよい手引である。
RxJava 2.0はRxJavaの真新しい実装である。このリリースはリアクティブストリーム仕様、ネットワークプロトコルと同様に実行環境(JVMとJavaScript)を対象としているノンブロッキングなバックプレッシャーで非同期のストリーム処理の標準を提供するための新提案をベースにしている。
リアクティブ実装はコンセプトがある。パブリッシャとサブスクライバである。データストリームにサブスクライブし、データの次のストリームを取得し、エラーを処理しコネクションを閉じる方法だけにとどまらない。
リアクティブストリーム仕様はjava.util.concurrent.FlowとしてJDK 9に含まれる予定である。以下のインタフェースはリアクティブストリーム仕様に一致する。おわかりのように、仕様は小さく、4つのインタフェースだけで定義される。
-
Flow.Processor<T,R>: サブスクライバとパブリッシャの両方として動作するコンポーネント。
-
Flow.Publisher<T>: サブスクライバが受け取る項目(と関連する制御メッセージ)のプロデューサ。
-
Flow.Subscriber<T>: メッセージの受信者。
-
Flow.Subscription: Flow.PublisherとFlow.Subscriberをリンクするメッセージ管理。
Springフレームワーク5もリアクティブに進んでいる。これがどのように見えるかを見るには、Josh Long氏のSpringフレームワーク5.0での関数型リアクティブエンドポイントを参照してほしい。
Vert.xはレッドハットのリアクティブJava実装である。
RxJava 2.0についてより学ぶために、InfoQはRxJava 2.0の主要なコントリビュータであるDavid Karnok氏にインタビューした。
InfoQ「まずはじめに、RxJava 2.0おめでとう!18ヶ月の開発、ほんとにすごいね。このリリースであなたがもっとも誇りに思っていることは何ですか?」
Karnok「ありがとう!ある意味で、私はこんなに長くならないことを願っていました。Ben Christensen氏、RxJavaを始めたオリジナルの作者が去りNetflixの誰もがいなくなりこれを前に進められなくなった時、10ヶ月の停止がありました。私がこの6月にリードする役割を引き受けたとき、多くの人がものごとをよりよくする方法を得ることについて争うであろうという確信が私にはありました。私はより進んだ、よりパフォーマンスのよいリアクティブストリームへの私の研究が効果を上げ、RxJava 2がその作業をすべて証明していることが誇りです。」
InfoQ:「RxJava 2.0において何が違いますか。それはどのように開発者を助けますか?」
Karnok「バージョン1と2には異なる点がたくさんあります。それらすべてをここで一覧にすることは不可能です。しかし、専用のウィキページを訪れてください。理解しやすい説明があります。おおまかには、私たちが今デファクトスタンダードのリアクティブストリーム仕様をサポートしており、多くの場所で重要なオーバーヘッドの削減があり、nullをもはや許可せず、バックプレッシャーをサポートするか欠いているかをベースに型を2つのグループに分けており、基本のリアクティブ型の間で明示的な相互運用を持っています。」
InfoQ「あなたがRxJavaはどんなところでもっとも使われると思いますか(たとえばIoTやリアルタイムデータ処理など)?」
Karnok「RxJavaは私が見たフィードバックをベースにするとAndroidコミュニティでより顕著に使われます。サーバサイドでは目下プロジェクトリアクタとAkkaが優位になっていると私は信じています。私はとくにIoTがRxJavaに言及するか使っている(Javaを必要とします)のを見ていませんが、それらは他の利用できるリアクティブライブラリをそれらのプラットフォーム上で使うかもしれません。リアルタイムデータ処理のために人々はまだ他の解決策、それらのほとんどは本当にリアクティブではないですが、そうしたものを使う傾向があります。この領域でリアクティブを強く求める他のプロバイダ(おそらくPivotal)については私は把握していません。」
InfoQ「支持が増加している説明としてRxJavaがAndroidに他の環境よりも提供している利点はなんですか?」
Karnok「私が見る限りでは、Androidは彼らのユーザがAsyncTaskやLooper/HandlerなどのようなAndroidだけのツールで非同期と並列の問題を解決するような"助け"を欲しています。
不幸にも、それらの設計と利用はまったく一貫しておらず、理解や予測が難しいかことがしばしばで、たいていAndroid開発者に不満をもたらします。これらは大いにコールバック地獄とメインスレッドで非同期処理をオフにするような困難への一因となります。
RxJavaの(マイクロソフトのReactiveXの設計から引き継がれた)設計はデータフロー指向で、処理のためにデータが現れたときからアクションが実行する場所と直交しています。加えて、エラー処理とレポートはフローの鍵です。AsyncTaskでは、手動でエラーの配信パターンを解決し、待機タスクをキャンセルしなければなりませんでした。反してRxJavaはその契約の一部としてそれを実行します。
実践的な検知では、バックグランドでそれぞれのサービスへ問い合わせ、それからメインスレッドで結果を表示するフローを持つことはRxJava (+Retrofit)では数行で表現できます。単純なスクリーンのローテーションは即座にサービス呼び出しをキャンセルするでしょう。
これはAndroid開発者にとってとてもすごい生産性の勝利です。そして単純さはリアクティブプログラミングのパラダイムシフトが要求する急な学習カーブを登る手助けをします。おそらく最後にはRxJavaはAndroidにはかなり魅力的でしょう。なぜならRxJavaはモバイルアプリビジネスにおいて個々の開発者やスタートアップ、小企業が"市場に出すまでの時間"を削減するからです。
現時点での私の意見では、デスクトップやサーバサイドJavaで比較できる問題はありません。人々はExecutorServiceを始動させFuture.get()を待つことをことを学習しており、データをGUIスレッドに送り戻すためのSwingUtilities.invokeLaterについて、そうでなければリクエストごとに1つのスレッド(3.0以前)であり、必然的に(データベースやサービス呼び出しなど)ブロッキングAPIを好むサーブレットAPIについて知っています。
デスクトップ/サーバのフォークはそれらのサービスが提供する(どのくらい簡単にサービスが書けるかということよりむしろ)ノンブロッキングな設計でのパフォーマンスの利点でより興味深いです。しかしながらAndroid開発と異なり、RxJavaを持つだけでは十分でなく、サーブレットAPIを置き換えるようなノンブロッキングなウェブサービスのための"正当な"標準はないので、それらのビジネスロジックを助けるためにフレームワークが多くの期待/必要性をそろえます。(そう、Spring (~Boot)やPlayがありますが、現時点ではそれらは私には少しごちゃっとしているように感じます)。」
InfoQ「HTTPは同期プロトコルでマイクロサービスを使うとき多くのバックプレッシャーを引き起こせます。AkkaやApache Kafkaのようなストリーミングプラットフォームはこれを解決する手助けをします。RxJava 2.0は自動的なバックプレッシャーを許可するために何かをしますか?」
Karnok「RxJava 2のFlowable型はリアクティブストリームのインタフェース/仕様を実装しており、バックプレッシャーをサポートしています。しかしながら、Javaレベルのバックプレッシャーはネットワークレベルのバックプレッシャーとはまったく異なります。私たちにとって、バックプレッシャーは次のことを意味します。どのくらい多くのオブジェクトがこれらのオブジェクトが型やサイズにおいて統一することができない異なるステージ間をパイプラインを通じて届けられるのかということです。ネットワークレベルではあるものはたいてい固定サイズのパケットを扱い、バックプレッシャーはそれより前に送られたパケットの承認の欠如を通じて現れます。古典的なセットアップにおいて、ネットワークのバックプレッシャーはJavaレベルでのデータのすべてのピースが書き込まれるまでリターンしないブロッキング呼び出しの上に現れます。Nettyのようなノンブロッキングなセットアップがあります。ここでは、ブロッキングは暗黙的なバッファリングに置き換えられます。私が知る限り、これらを処理する個別の、統一されていない、リアクティブストリーム互換でない方法だけがあります(すなわちどれがスピンオーバー/リトライしなければならないかを書き込み可能かの確認のためにチェックする)。私が見たものと成功の程度は異なりますが2つの世界を橋渡ししようとするライブラリ(RxNettyやSpringのいくらか)が存在します。」
InfoQ「あなたはリアクティブフレームワークは大量のトラフィックとリアルタイムデータを処理するために必要と思いますか?」
Karnok「それは問題の複雑さに依存します。たとえば、もしあなたの作業がビッグデータのソースの文字数を数えることなら、それをするより早くより専門の方法があります。もしあなたの作業が何か詳細にしたものを返すために入って来るデータのストリームの上にサービスから結果を構成することならリアクティブベースの解決策は完全に適しています。私が知る限り、リアクティブストリーム近辺のほとんどのライブラリとフレームワークはスループットのために設計されており、実はレイテンシのためではありません。たとえば、高頻度の取引において、予測がつくレイテンシはとても重要で、Aeronによって簡単に接続することができますが、予測できないレイテンシのふるまいのためにRxJavaにとって主な焦点ではありません。」
InfoQ「HTTP/2はHTTP/1.1が持っていたスケーラビリティの問題を解決する手助けとなりますか?」
Karnok「これはRxJavaに関連することではなく、私は個人的にHTTP/2を試しておらず仕様を読んだだけです。同一のチャンネルでの多重送信は明示的なストリームごとのバックプレッシャーのサポートに加えて疑いなく勝利です(つまり、たとえネットワークが届いたとしても、クライアントはその量においてはまだデータを処理できないかもしれません)。私は技術的な詳細をすべて知っているわけではありませんが、Spring Reactive WebがHTTP/2トランスポートを利用可能になればサポートすると信じています。しかしそれらはリアクティブの抽象化の背後にある複雑性をすべて隠蔽します。そのためあなたは望むなら処理パイプラインをRxJava 2とReactor 3の用語で記述することができます。」
InfoQ「Java 9はリアクティブな機能をいくつか含むことを計画しています。これは完全な仕様ですか?」
Karnok「いいえ。Java 9は7つのメソッド呼び出しがある4つのJavaインタフェースを含む予定です。ストリームのような、もしくはRxのようなAPIはその上にありませんし、JDKの機能でその上に構築されているものはありません。」
InfoQ「もしJDKにそれが正しく構築されれば、RxJavaの必要性はなくなりますか?」
Karnok「いいえ。私はRxJavaのような真の、証明されたライブラリがより必要とされるであろうことを信じています。一度ツールチェインがJava 9まで成長すれば、私たちはたしかにアダプタを提供するでしょう。そしてRxJava 3をJava 9の機能(VarHandles)の上に変換(もしくは書き直しを)するかもしれません。
私が恐れていることの1つはJava 9が一度外に出れば、多くの人が彼ら自身のライブラリ(個人でも企業でも)を書こうとするであろうことです。"市場"は大きいブランドの低品質の解決策で薄められます。増加する"RxJavaはXとどのように異なるのか"という質問の量に注意が払われません。
私の個人的な意見は、これはあるライブラリやフレームワークがそれら自身をリアクティブストリームとして宣伝しているが、それに基づいたものを届けることに失敗しているところである、リアクティブストリーム周辺ですでに今日起こっていることだということです。私の(おそらくバイアスがかかった)推測は、RxJava 2は可能な限り最高のリアクティブストリームベースの解決策にもっとも近いライブラリ/技術であるということです。」
InfoQ「RxJavaで次に来るものは何ですか?」
Karnok「私たちにはRxJava 2を開発している間Jake Wharton氏のようなすばらしいレビュワーがいました。不幸なことに、開発プレビューとリリース候補では十分注目されませんでした。私たちの努力にもかかわらず、小さな問題と見落としが最終リリースに滑り込みました。私はこの数ヶ月には大きな問題は予期していませんが、私たちは時折ユーザベースをサポートするために新しい処理を追加するのと同様にバージョン1と2の両方で修正し続ける予定です。RxAndroidのようないくつかの関連ライブラリは今RxJava 2互換のバージョンを提供しています。しかし他のライブラリの大半はまだ前に進める方法を決めていません。RxJavaに関して、私は6ヶ月以内にRxJava 1を終了させることを計画しています(つまりそれ以降はバグフィックスのみ)。部分的には今しばらくの間私の"1人軍隊"での増加するメンテナンス負担のためです。部分的には残りの人にRxJava 2のエコシステムに切り替えることを"奨励する"ためです。RxJava 3のためとしては、私はまだ何も具体的な計画はありません。オペレータフュージョンと呼ばれる要素(これは私たちのパフォーマンスに大きな推進力を与えます)をリアクティブストリーム仕様の標準拡張とすることと同様に、型に従って、もしくはバックプレッシャーのサポートに従ってライブラリを分割することについて議論が進行中です。
Rate this Article
- Editor Review
- Chief Editor Action