40
RxJava + Vert.x + jOOλ Microservice的な何かを 作ってみた たけうち ひでゆき

RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

RxJava + Vert.x + jOOλ で Microservice的な何かを

作ってみた

たけうち ひでゆき

Page 2: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

たけうち ひでゆき@chimerast

株式会社ユーザベース チーフテクノロジスト / イノベーション担当執行役員

Page 3: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき
Page 4: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

企業・業界分析の 情報プラットフォーム

全世界300万社超 / 550業界のデータ

世界最大級のM&Aデータ

Page 5: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

経済情報に特化した ソーシャル経済ニュース サービス

経済ニュースを 解説コメント付きで まとめ読み

130万ユーザぐらい

Page 6: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

本題

Page 7: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

RxJava + Vert.x + jOOλ で作ったもの

チャート描画用のRESTfulなAPIサービス• D3.jsでチャートを描画するために会社情報やら統計情報やら必要なデータをいろんなところからかき集めてきてJSONで返す

Page 8: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

これを生成したい

D3.jsで描画

Page 9: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

サービス構成Companies API

Stats API

Media API

Chart API ブラウザ

Microservices的な何か

Page 10: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

サービス登場人物Companies API 企業名称や財務・株価情報データ等を扱うサービス

Stats API 統計名称や統計情報データ等を扱うサービス

Media API チャートの素となる情報を扱うサービス チャートの素 = どの企業のどの勘定科目でチャートを作るかの指定

Page 11: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

チャート用JSONが返るまでの流れ1. Media API からチャートの素を取得する

2. チャートの素で指定されたデータをCompanies API や Stats APIに複数回リクエストを投げて取得する

3. 結果をまとめてJSONにしてブラウザに返す

Page 12: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき
Page 13: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

データの取得Companies API

Stats API

Media API

Chart API ブラウザ

②, ③, ④, ⑤, ⑥, …

Page 14: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

AWSオンプレミス

データセンターの壁Companies API

Stats API

Media API

Chart API ブラウザ

Page 15: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

今回の問題

1. データセンターの壁を越えて

2. 複数回独立なリクエストを投げてデータを取得

3. それをまとめ上げてJSONとして返す

Page 16: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

今回の選択

Page 17: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Vert.x + Vert.x-Web• ノンブロッキングI/Oな高レベルフレームワーク

• シングルスレッドで大量のコネクションをさばける

• 全てがコールバックで結果が返る非同期API

• Node.js + Express 的な存在 (というかまんまそれ)

• マルチスレッドでも動く Verticleという概念、EventBusという概念

Page 18: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Vert.x-Webのコードの雰囲気

/helloをHTTP GETすると"Hello World!!!"という文字列が返る

router.get("/hello").handler(routingContext -> { routingContext.response().end("Hello world!!!"); });

Page 19: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

なぜVert.xを選択したか?• 1リクエストで、バックエンドのAPIに複数回独立したリクエストを投げる必要があった

• ブロッキングI/Oでやると並列化してスレッド数が爆増か直列化してレスポンスが激遅くなるか

Page 20: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

RxJava

• Reactive ExtensionsのJava実装

• 非同期の複数イベントうまく扱うための仕組みと関数群

• RxJava = Promise × Stream

Page 21: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Reactive Extensions

• http://www.slideshare.net/stefanmayer13/functional-reactive-programming-with-rxjs

Page 22: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき
Page 23: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき
Page 24: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

なぜRxJavaを選択したか?• Vert.x 単体だとコールバック地獄に陥る

• SQLでトランザクション使いつつのSelect&Updateとかマジで地獄

• 一度に複数のHTTPリクエストを並列で投げそれをエレガントに管理したかった

• ぶっちゃけPromise的な何かが欲しかった

Page 25: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

RxJavaを使わなかった場合(イメージ)client.getConnection(result1 -> { SQLConnection connection = result1.result(); connection.setAutoCommit(false, result2 -> { connection.queryWithParams("SELECT ...", params3, result3 -> { connection.updateWithParams("UPDATE ...", params4, result4 -> { connection.commit(result5 -> { connection.close(result6 -> { successCallback(); }); }); }); }); }); }); エラー処理を入れるともっとひどいことに。。。

Page 26: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

RxJavaを使った場合(イメージ)

client.getConnectionObservable().flatMap(connection -> { return connection.setAutoCommitObservable(false) .flatMap(result -> connection.queryWithParamsObservable("SELECT ...", params1)) .flatMap(result -> connection.updateWithParamsObservable("UPDATE ...", params2))) .flatMap(result -> connection.commitObservable()) .flatMap(result -> connection.closeObservable()); });

エラー処理はsubscribeで一回書くだけ!

Page 27: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Vert.x + Vert.x-Web + RxJava

≒ Node.js + Express + Promise (bluebird)

Page 28: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

今回の開発でよく使った関数

• observable.map() • observable.flatMap() • Observable.zip() • observable.onErrorReturn()

Page 29: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

observable.map()

• あるリクエストの結果を別の形に変換する

observableA .map(responseA -> { .. responseAからresponseZを作る .. return responseZ; });

Page 30: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

observable.flatMap()• あるリクエストの結果をもとに別のリクエストを投げる時に使う

observableA .flatMap(responseA -> { .. responseAからobervableBを構築する .. return observableB; });

Page 31: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Observable.zip()• 複数の独立したリクエストを並列で投げるときに使う

Observable.zip( observableA, observableB, (responseA, responseB) -> { .. responseAとresponseBでzipの返り値を作る .. });

Page 32: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

observable.onErrorReturn()

• 404エラーだった場合にも後続の処理を続行したいときに使う

observable .map(Optional::of) .onErrorReturn(e -> Optional.empty());

Page 33: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

実際の良くあったコード(雰囲気)observableA // Media APIからチャートの素を取得 .flatMap(responseA -> { .. responseAからobservableB, C, D (企業B, C, D)を生成 .. return Observable.zip( observableB.map(Optional::of).onErrorReturn(e -> Optional.empty()), observableC.map(Optional::of).onErrorReturn(e -> Optional.empty()), observableD.map(Optional::of).onErrorReturn(e -> Optional.empty()), (optionalResponseB, optionalResponseC, optionalResponseD) -> { .. responseAとoptionalResponseB, C, DからresponseZを生成 .. return responseZ; // チャートのモデル }); });

Page 34: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

jOOλ• Java8 SDKでかゆいところに手が届いていない部分を補完してくれるちっちゃなライブラリ

• Observable.zip()のためにTupleが欲しかったから使った

• Streamが微妙に足りてないところを補完するSeqSeq.zipWithIndex()とかたまに使ったりする

Page 35: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Vert.x-Rx• Vert.xの各モジュールをRxJava化するモジュール

• たまに用意されていないメソッドがあるので困る

• ただのwrapperなので途中からVert.x-Rxを使える

JDBCClient.createShared( // JDBCClientはRxのもの new io.vertx.rxjava.core.Vertx(vertx), // vertxは非Rx config.getJsonObject("jdbc").getJsonObject(db), db);

Page 36: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

Vert.x Rest client• https://github.com/hubrick/vertx-rest-client • バックエンドのRESTなAPIを叩くのに使った

• RxJavaにも対応していて使いやすい

• レスポンスをJacksonでデシリアライズしたTが、Ovservable<T>の形で取得できる

Page 37: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

まとめ• Vert.xを使うとノンブロッキングI/OでバックエンドのAPIに並列にリクエストを投げられるよ

• RxJavaを使うとVert.xのコールバック地獄から抜け出せるよ

• jOOλはあるとちょこっと便利なライブラリだよ

Page 38: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

感想• Vert.x + RxJava はとても相性がいい。無いと死ぬ

• 並列、並列、並列

• Java8に対応していてラムダ式使いまくりで気持ちいい

• バックエンドAPIをいじめている感が出て気持ちいい俺はまだまだいけるぞ的な

Page 39: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

エンジニア募集

• 株式会社ユーザベース、株式会社ニューズピックスではMicroservices的な何かを作りたいエンジニアを 募集しています

• 興味がある方は是非お声がけを。Wantedlyからでも。

Page 40: RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた · RxJava + Vert.x + jOOλ で Microservice的な何かを 作ってみた たけうち ひでゆき

提 供