RxJava + Vert.x + jOOλ で Microservice 的な何かを作ってみた

RxJava + Vert.x + jOOλ で Microservice 的な何かを作ってみた

2016年2月25日に行われた、Rx Ja Night 2016 #1での発表資料です。

8a43d544df4886ea5ef714e78f3420a7?s=128

Hideyuki Takeuchi

February 25, 2016
Tweet

Transcript

  1. RxJava + Vert.x + jOOλ Ͱ MicroserviceతͳԿ͔Λ ࡞ͬͯΈͨ ͚ͨ͏ͪɹͻͰΏ͖

  2. ͚ͨ͏ͪɹͻͰΏ͖ @chimerast ৬ۀ: ӬԕͷNEET झຯ: ϓϩάϥϜͷຐվ଄
 (ϝλϓϩάϥϛϯάͱ͔)

  3. ੈΛ೜ͿԾͷ࢟ גࣜձࣾϢʔβϕʔε
 νʔϑςΫϊϩδετ
 / Πϊϕʔγϣϯ୲౰ࣥߦ໾һ ϥΠϑΠζςοΫגࣜձࣾ
 ཹֶCTO ΦʔϓϯιʔεϓϩδΣΫτ E2D3
 νʔϑΠϊϕʔγϣϯΦϑΟαʔ(?)

  4. ࠓ೔ͷ͓࿩ Ͱͷࣄྫ

  5. None
  6. اۀɾۀք෼ੳͷ
 ৘ใϓϥοτϑΥʔϜ શੈք300ສࣾ௒ / 
 550ۀքͷσʔλ ੈք࠷େڃͷM&Aσʔλ

  7. ܦࡁ৘ใʹಛԽͨ͠
 ιʔγϟϧܦࡁχϡʔε
 αʔϏε ܦࡁχϡʔεΛ
 ղઆίϝϯτ෇͖Ͱ
 ·ͱΊಡΈ 120ສϢʔβ͙Β͍

  8. ຊ୊

  9. RxJava + Vert.x + jOOλ Ͱ࡞ͬͨ΋ͷ νϟʔτඳը༻ͷRESTfulͳAPIαʔϏε • D3.jsͰνϟʔτΛඳը͢ΔͨΊʹ
 ձࣾ৘ใ΍Β౷ܭ৘ใ΍Β


    ඞཁͳσʔλΛ͍ΖΜͳͱ͜Ζ͔Β
 ͔͖ूΊ͖ͯͯJSONͰฦ͢
  10. ͜ΕΛੜ੒͍ͨ͠ D3.jsͰඳը

  11. αʔϏεߏ੒ Companies API Stats API Media API Chart API ϒϥ΢β

    MicroservicesతͳԿ͔
  12. αʔϏεొ৔ਓ෺ Companies API اۀ໊শ΍ࡒ຿ɾגՁ৘ใσʔλ౳Λѻ͏αʔϏε Stats API ౷ܭ໊শ΍౷ܭ৘ใσʔλ౳Λѻ͏αʔϏε Media API νϟʔτͷૉͱͳΔ৘ใΛѻ͏αʔϏε


    νϟʔτͷૉ ʹ ͲͷاۀͷͲͷצఆՊ໨ͰνϟʔτΛ࡞Δ͔ͷࢦఆ
  13. νϟʔτ༻JSON͕ฦΔ·ͰͷྲྀΕ 1. Media API ͔ΒνϟʔτͷૉΛऔಘ͢Δ 2. νϟʔτͷૉͰࢦఆ͞ΕͨσʔλΛ
 Companies API ΍

    Stats APIʹ
 ෳ਺ճϦΫΤετΛ౤͛ͯऔಘ͢Δ 3. ݁ՌΛ·ͱΊͯJSONʹͯ͠ϒϥ΢βʹฦ͢
  14. None
  15. σʔλͷऔಘ Companies API Stats API Media API Chart API ϒϥ΢β

    ᶃ ᶄ, ᶅ, ᶆ, ᶇ, ᶈ, …
  16. AWS ΦϯϓϨϛε σʔληϯλʔͷน Companies API Stats API Media API Chart

    API ϒϥ΢β
  17. ࠓճͷ໰୊ 1. σʔληϯλʔͷนΛӽ͑ͯ 2. ෳ਺ճಠཱͳϦΫΤετΛ౤͛ͯσʔλΛऔಘ 3. ͦΕΛ·ͱΊ্͛ͯJSONͱͯ͠ฦ͢

  18. ࠓճͷબ୒

  19. Vert.x + Vert.x-Web • ϊϯϒϩοΩϯάI/OͳߴϨϕϧϑϨʔϜϫʔΫ • γϯάϧεϨουͰେྔͷίωΫγϣϯΛ͞͹͚Δ • શ͕ͯίʔϧόοΫͰ݁Ռ͕ฦΔඇಉظAPI •

    Node.js + Express తͳଘࡏ (ͱ͍͏͔·Μ·ͦΕ) • ϚϧνεϨουͰ΋ಈ͘
 Verticleͱ͍͏֓೦ɺEventBusͱ͍͏֓೦
  20. Vert.x-Webͷίʔυͷงғؾ /helloΛHTTP GET͢Δͱ"Hello World!!!"ͱ͍͏
 จࣈྻ͕ฦΔ router.get("/hello").handler(routingContext -> { routingContext.response().end("Hello world!!!");

    });
  21. ͳͥVert.xΛબ୒͔ͨ͠ʁ • ̍ϦΫΤετͰɺόοΫΤϯυͷAPIʹෳ਺ճ
 ಠཱͨ͠ϦΫΤετΛ౤͛Δඞཁ͕͋ͬͨ • ϒϩοΩϯάI/OͰ΍Δͱ
 ฒྻԽͯ͠εϨου਺͕ര૿͔
 ௚ྻԽͯ͠Ϩεϙϯε͕ܹ஗͘ͳΔ͔

  22. RxJava • ࠓճͷษڧձͷओ୊ • ͨͿΜ୭͔͕ৄ͘͠આ໌ͯ͠
 ͘Ε͍ͯΔ͸ͣ(ر๬త؍ଌ) • ๻΋ษڧ͠ʹ͜͜ʹདྷ·ͨ͠ʂ

  23. ͳͥRxJavaΛબ୒͔ͨ͠ʁ • Vert.x ୯ମͩͱίʔϧόοΫ஍ࠈʹؕΔ • SQLͰτϥϯβΫγϣϯ࢖͍ͭͭͷSelect&Updateͱ͔
 ϚδͰ஍ࠈ • Ұ౓ʹෳ਺ͷHTTPϦΫΤετΛฒྻͰ౤͛
 ͦΕΛΤϨΨϯτʹ؅ཧ͔ͨͬͨ͠

    • ͿͬͪΌ͚PromiseతͳԿ͔͕ཉ͔ͬͨ͠
  24. 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(); }); }); }); }); }); }); ΤϥʔॲཧΛೖΕΔͱ΋ͬͱͻͲ͍͜ͱʹɻɻɻ
  25. 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ͰҰճॻ͚ͩ͘ʂ
  26. Vert.x + Vert.x-Web + RxJava ≒ Node.js + Express +

    Promise (bluebird)
  27. ࠓճͷ։ൃͰΑ͘࢖ͬͨؔ਺ • observable.map() • observable.flatMap() • Observable.zip() • observable.onErrorReturn()

  28. observable.map() • ͋ΔϦΫΤετͷ݁ՌΛผͷܗʹม׵͢Δ observableA .map(responseA -> { .. responseAからresponseZを作る ..

    return responseZ; });
  29. observable.flatMap() • ͋ΔϦΫΤετͷ݁ՌΛ΋ͱʹ
 ผͷϦΫΤετΛ౤͛Δ࣌ʹ࢖͏ observableA .flatMap(responseA -> { .. responseAからobervableBを構築する

    .. return observableB; });
  30. Observable.zip() • ෳ਺ͷಠཱͨ͠ϦΫΤετΛฒྻͰ
 ౤͛Δͱ͖ʹ࢖͏ Observable.zip( observableA, observableB, (responseA, responseB) ->

    { .. responseAとresponseBでzipの返り値を作る .. });
  31. observable.onErrorReturn() • 404Τϥʔͩͬͨ৔߹ʹ΋ޙଓͷॲཧΛ
 ଓߦ͍ͨ͠ͱ͖ʹ࢖͏ observable .map(Optional::of) .onErrorReturn(e -> Optional.empty());

  32. ࣮ࡍͷྑ͋ͬͨ͘ίʔυ(งғؾ) 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; // チャートのモデル }); });
  33. jOOλ • Java8 SDKͰ͔Ώ͍ͱ͜Ζʹख͕ಧ͍͍ͯͳ͍෦෼Λ
 ิ׬ͯ͘͠ΕΔͪͬͪΌͳϥΠϒϥϦ • Observable.zip()ͷͨΊʹTuple͕ཉ͔͔ͬͨ͠Β
 ࢖ͬͨ • Stream͕ඍົʹ଍Γͯͳ͍ͱ͜ΖΛิ׬͢ΔSeq


    Seq.zipWithIndex()ͱ͔ͨ·ʹ࢖ͬͨΓ͢Δ
  34. 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);
  35. Vert.x Rest client • https://github.com/hubrick/vertx-rest-client • όοΫΤϯυͷRESTͳAPIΛୟ͘ͷʹ࢖ͬͨ • RxJavaʹ΋ରԠ͍ͯͯ͠࢖͍΍͍͢ •

    ϨεϙϯεΛJacksonͰσγϦΞϥΠζͨ͠T͕ɺ
 Ovservable<T>ͷܗͰऔಘͰ͖Δ
  36. FAQ Q. ࠓServlet࢖ͬͯΔΜ͚ͩͲɺRxJava࢖͏ͱ
 όοΫΤϯυͷAPIʹฒྻͰϦΫΤετ౤͛ΒΕΔͷʁ A. RxJava୯ମͰ͸Ͱ͖·ͤΜɻ
 ExecutorServiceͱFutureͰ৐Γ੾͍ͬͯͩ͘͞
 (εϨουফඅ͢Δ͚Ͳ)ɻ

  37. ·ͱΊ • Vert.xΛ࢖͏ͱϊϯϒϩοΩϯάI/OͰ
 όοΫΤϯυͷAPIʹฒྻʹϦΫΤετΛ౤͛ΒΕΔΑ • RxJavaΛ࢖͏ͱVert.xͷίʔϧόοΫ஍ࠈ͔Β
 ൈ͚ग़ͤΔΑ • jOOλ͸͋Δͱͪΐͬ͜ͱศརͳϥΠϒϥϦͩΑ

  38. ײ૝ • Vert.x + RxJava ͸ͱͯ΋૬ੑ͕͍͍ɻແ͍ͱࢮ͵ • ฒྻɺฒྻɺฒྻ • Java8ʹରԠ͍ͯͯ͠ϥϜμࣜ࢖͍·͘ΓͰؾ͍͍࣋ͪ

    • όοΫΤϯυAPIΛ͍͡Ί͍ͯΔײ͕ग़ͯؾ͍͍࣋ͪ
 Զ͸·ͩ·͍͚ͩΔͧతͳ
  39. ΤϯδχΞืू • גࣜձࣾϢʔβϕʔεɺגࣜձࣾχϡʔζϐοΫεͰ͸
 MicroservicesతͳԿ͔Λ࡞Γ͍ͨΤϯδχΞΛ
 ืू͍ͯ͠·͢ • ڵຯ͕͋Δํ͸ੋඇ͓੠͕͚ΛɻWantedly͔ΒͰ΋ɻ

  40. ΤϯδχΞืू • ϥΠϑΠζςοΫגࣜձࣾͰ͸
 JavaͰDDDΛ΍Γ͍ͨΤϯδχΞΛ
 ืू͍ͯ͠·͢ • ڵຯ͕͋Δํ͸ੋඇ͓੠͕͚ΛɻWantedly͔ΒͰ΋ɻ

  41. ΤϯδχΞืू • ΦʔϓϯιʔεϓϩδΣΫτE2D3Ͱ͸
 σʔλՄࢹԽʹڵຯ͕͋ΔΤϯδχΞΛ
 ืू͍ͯ͠·͢ • ڵຯ͕͋Δํ͸ੋඇ͓੠͕͚Λɻ΋͘΋͘ձࢀՃͰ΋ɻ

  42. ఏ ڙ