Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

JJUG CCC 2017 Spring Seasar2からSpringへ移行した俺たちのアプリケーションがマイクロサービスアーキテクチャへ歩み始めた

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige

Hier ansehen

1 von 111 Anzeige

JJUG CCC 2017 Spring Seasar2からSpringへ移行した俺たちのアプリケーションがマイクロサービスアーキテクチャへ歩み始めた

Herunterladen, um offline zu lesen

2011年にリリースした弊社フリューのアプリケーションは、利用者が年々増加し、1000万人を超えました。それに伴い、機能を追加、改修しているため肥大化したモノリシックアプリケーションとなりました。また開発チームも複数あり、それぞれが機能を開発し、毎日のようにデプロイ、リリースしています。
こうした現状から、ドメインごとにアプリケーションを分割したいという欲求が生まれ、マイクロサービスアーキテクチャに変えていくことにしました。もちろん今もサービスを運用、新機能開発していく中でゆるやかに実施していくため、完成したわけではありません。このセッションでは、現実に運用しているアプリケーションに対して、マイクロサービス構築に何を使い、どのように一歩踏み出し、その結果チームは何を実現し何を得られたか、ということを話します。
JJUG CCCでは弊社フリューのアーキテクチャの変遷について、2016 Spring、2016 Fallとセッションをしてきました。Springでは"Seasar2で作った俺たちのサービスの今"、Fallでは"10年運用している画像サービスでのJavaの活用と今後の展望"と、Seasar2からSpring Framework/MVCに移行した話をしました。今回は、このアプリケーションから特定の機能を取り出してマイクロサービスとしてSpring Boot、Spring Cloud Netflix(ribbon/Eureka/Hystrix)で構築し、既存の手動テストをパスさせるためSpring Cloud Contract Stub Runnerを活用した点を中心に話します。また、私以外Spring自体をほぼ知らないチームで、どのように習得を進めたかという点にも触れます。
すでにこれらの技術をご存知の方にはこのセッションは適切でない可能性があります。また、ベストプラクティスでも、Spring Cloudのすべてのプロダクトを使っているわけでもありません。それでも、1つの現場の事例としてみなさんのご参考になれば幸いです。

2011年にリリースした弊社フリューのアプリケーションは、利用者が年々増加し、1000万人を超えました。それに伴い、機能を追加、改修しているため肥大化したモノリシックアプリケーションとなりました。また開発チームも複数あり、それぞれが機能を開発し、毎日のようにデプロイ、リリースしています。
こうした現状から、ドメインごとにアプリケーションを分割したいという欲求が生まれ、マイクロサービスアーキテクチャに変えていくことにしました。もちろん今もサービスを運用、新機能開発していく中でゆるやかに実施していくため、完成したわけではありません。このセッションでは、現実に運用しているアプリケーションに対して、マイクロサービス構築に何を使い、どのように一歩踏み出し、その結果チームは何を実現し何を得られたか、ということを話します。
JJUG CCCでは弊社フリューのアーキテクチャの変遷について、2016 Spring、2016 Fallとセッションをしてきました。Springでは"Seasar2で作った俺たちのサービスの今"、Fallでは"10年運用している画像サービスでのJavaの活用と今後の展望"と、Seasar2からSpring Framework/MVCに移行した話をしました。今回は、このアプリケーションから特定の機能を取り出してマイクロサービスとしてSpring Boot、Spring Cloud Netflix(ribbon/Eureka/Hystrix)で構築し、既存の手動テストをパスさせるためSpring Cloud Contract Stub Runnerを活用した点を中心に話します。また、私以外Spring自体をほぼ知らないチームで、どのように習得を進めたかという点にも触れます。
すでにこれらの技術をご存知の方にはこのセッションは適切でない可能性があります。また、ベストプラクティスでも、Spring Cloudのすべてのプロダクトを使っているわけでもありません。それでも、1つの現場の事例としてみなさんのご参考になれば幸いです。

Anzeige
Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (20)

Anzeige

Ähnlich wie JJUG CCC 2017 Spring Seasar2からSpringへ移行した俺たちのアプリケーションがマイクロサービスアーキテクチャへ歩み始めた (20)

Weitere von Koichi Sakata (20)

Anzeige

Aktuellste (20)

JJUG CCC 2017 Spring Seasar2からSpringへ移行した俺たちのアプリケーションがマイクロサービスアーキテクチャへ歩み始めた

  1. 1. Seasar2から Springへ移行した 俺たちのアプリケーションが マイクロサービス アーキテクチャへ歩み始めた フリュー株式会社 / 関西Javaエンジニアの会 阪田 浩一 @jyukutyo #ccc_f5
  2. 2. 関ジャバ会長は、フリュー所属 通称: じゅくちょー @jyukutyo
  3. 3. 私のセッションは • 私の現場の、私のコンテキストでの、 現実解です。 • 書籍にあるような理想形を実現する ものではありません。 • アカデミックさよりビジネスと技術 を等価で捉えています。
  4. 4. Agenda • Spring + Netflix OSSでの マイクロサービス化 • 試験でのSpring Cloud Contract Stub Runnerの利用
  5. 5. 伝えたいこと マイクロサービス、 はじめの一歩くらいなら そんな大仰なことじゃない
  6. 6. サービスの変容を連載中 • 2015 Spring • クリスマスを支える俺たちとJava • 2016 Spring • Seasar2で作った俺たちのサービスの今 • 2016 Fall • 10年運用している画像サービスでの Javaの活用と今後の展望 • 2017 Spring <- now • Seasar2からSpringへ移行した 俺たちのアプリケーションが マイクロサービスアーキテクチャへ歩み始めた
  7. 7. 前回までのあらすじ
  8. 8. Application (WAR) S2Servlet DispatcherServlet DIコンテナ DIコンテナ Cubby Action Service / Logic S2Dao DAO Interceptor MVC Controller Service / Logic S2Dao DAO Interceptor Doma2 DAO 同一のJS/CSS/テンプレートファイル
  9. 9. 1つのWARに 2つのDIコンテナ
  10. 10. Springだけに なるように 作業中だけど、 今回はスコープ外
  11. 11. 対象について
  12. 12. 対象アプリケーション サービス名 ピクトリンク 開始 2011年 (前身サービスは もっと以前から) 利用者数 1,000万人超 (有料会員数は秘密) 主な機能 プリントシール機で 撮影した画像を 取得する + SNS的な
  13. 13. 対象アプリケーション サービス名 ピクトリンク 提供 Webアプリケーション iOSアプリ Androidアプリ 課金 キャリア課金 d/au/SB 楽天ID決済 クレカ決済 iOS課金
  14. 14. ユーザ数に比例して •13万行のコードに (ライブラリは含まず)
  15. 15. 並行開発/デイリーリリース リポジ トリ チームA チームCチームB
  16. 16. あるある • 今日チームAがリリースするから チームBはちょっと待って • ビルド時間が長い
  17. 17. あるある • RDBMSが巨大になってきた • Oracle EE RACを今年購入した • 13億行のテーブル... • 負荷増大に対してフルスペックの サーバを追加する • お高い • オンプレミスです
  18. 18. よろしい、ならば
  19. 19. サービスごとにスケール的な
  20. 20. 前提条件 開発はビジネス要件 (新機能開発・既存改修) と並行して実施する
  21. 21. 第1目標 サービスクラス以降の 処理を単純に 1つのマイクロサービスに してみる
  22. 22. 理由 初めからきれいな ドメイン分割を 気にしすぎても 前に進めなさそう
  23. 23. 理由 やってみて フィードバックを得て、 サービスを 運用改善していく
  24. 24. Application (WAR) S2Servlet DispatcherServlet DIコンテナ DIコンテナ Cubby Action Service / Logic S2Dao DAO Interceptor MVC Controller Service / Logic S2Dao DAO Interceptor Doma2 DAO 同一のJS/CSS/テンプレートファイル
  25. 25. 何が必要か クライ アント サービス インスタンスA サービス インスタンスB サービス インスタンスC 10.5.83.126 10.5.83.127 10.5.83.128 ロードバランスは どうする? インスタンス数は 動的に変更できる? ?
  26. 26. 何が必要か クライ アント サービス インスタンスA サービス インスタンスB サービス インスタンスC 10.5.83.126 10.5.83.127 サービス ディスカバリ ディスカバリを 認識する HTTPクライアント 126,127,128 10.5.83.128
  27. 27. • eureka • Service Discovery • ribbon • Client Side Load Balancing • Hystrix • Circuit Breaker • など
  28. 28. クライ アント サービス インスタンスA サービス インスタンスB サービス インスタンスC 10.5.83.126 10.5.83.127 Eureka ribbon 10.5.83.128
  29. 29. Spring • Spring Cloud Netflix • Spring Bootと簡単に連携できる
  30. 30. 俺たちのサービス Spring MVC Spring Boot Spring Boot Spring Boot Eureka ribbon !? Spring Cloud Netflix Eureka
  31. 31. Seasar2部分が 残っているので、 Spring Bootではなく MVCのまま
  32. 32. 最初の移行対象 クレジットカード決済 機能
  33. 33. クレジットカード決済 • 外部の決済代行サービスを利用している • 決済手段としては利用が多くない • かといってどうでもいい機能でもない
  34. 34. メンバーの状況 • Spring MVCは慣れてきた • Spring Boot/Cloudは知らない • マイクロサービスは概念から 知らない
  35. 35. メンバーの学習 • 各自書籍で学ぶ • マイクロサービス概念、 Netflix OSSは 説明会を数回
  36. 36. 機械的かと思いきや コードを変更する 部分も多い
  37. 37. この部分は クライアント?MS? どっちに置く?
  38. 38. 処理の順序とか なんかこう入り組んだ コードとか
  39. 39. ユニットテスト重要 もともと各クラスに 必ずテストクラスを 作っていた
  40. 40. 期間 2016年11月〜17年1月 リリース 2017年1月末
  41. 41. ログ監視 Spring Boot ログファイル1 Spring Boot ログファイル2 インフラチームが構築
  42. 42. プロセス監視など • 監視会社に追加依頼
  43. 43. 2つめの移行 別の課金機能を 同様に作業して リリース済み
  44. 44. 課題 マイクロサービスとして 堂々と紹介できる ほど完成していない
  45. 45. ビッグバンはしない。 これまで通り 長期間に渡って 少しずつ進める
  46. 46. エンジニアの学習、 フィードバックループ にとって一番いい
  47. 47. 課題 すべてのサービスが 同じRDBMSを 使っている
  48. 48. 書籍にもあるように アンチパターン
  49. 49. これを
  50. 50. こうしたい
  51. 51. 課題 オーケストレーション 方式
  52. 52. オーケストレーション アプリケーション サービスA サービスB サービスCアプリケーション 呼び出し側の 負担が大きい
  53. 53. 課題 コレオグラフィも 検討したい
  54. 54. コレオグラフィで アプリケー ション イベント サービスA サービスB サービスC パブリッシュ/ サブスクライブ サービスD
  55. 55. Spring Cloud Stream
  56. 56. 固有の課題 • 元のアプリケーションが Spring BootではなくMVCである • Spring Cloud使えない • ribbon/Eurekaをそのまま使う
  57. 57. ribbonでのAPI呼び出し コード
  58. 58. @Resource LoadBalancingHttpClient<ByteBuf, ByteBuf> ribbonClient; ... HttpClientRequest<ByteBuf> request = HttpClientRequest.createPost(url) .withContent(“...”) .withHeader("Content-type", "application/json"); HttpClientResponse<ByteBuf> httpClientResponse = ribbonClient .submit(request) .toBlocking() .first(); HttpResponseStatus status = httpClientResponse.getStatus();
  59. 59. ribbonとEurekaの連携は ライブラリ ribbon-eureka を使う
  60. 60. Spring Cloudなら すぐできるのに...! と思うこと多数
  61. 61. 秋までには 元のアプリケーションも Bootに移行したい
  62. 62. そうしたら Spring Cloud Sluethで 分散トレーシングも 入れれる
  63. 63. チームでの感想 • コード分割 + Bootのパワーで 起動が早く動作確認しやすく なった • これだけでも十分メリットだ
  64. 64. チームでの感想 • Spring Bootはテストコード が書きやすい • Controller • Application
  65. 65. チームでの感想 • マイクロサービスへの分割で、 サービス全体を手動テストして 確認する数が減った
  66. 66. ここでテストについて
  67. 67. いわゆる結合試験 • Excelに書いてある • テスト用レコードを登録し、 手でスマホを操作してテストする • 何割かGauge/Selenideで 自動テストあり
  68. 68. 既存のテスト項目を そのまま実施して、 OKなら移行完了としたい
  69. 69. 自動テストは 課金関連では3割ほど。 あとは手で再実施...
  70. 70. その中に 悩ましいケースが...
  71. 71. throw an exception and return 500 HTTP status code
  72. 72. 人為的に エラー動作を どのように起こすか?
  73. 73. マイクロサービスの コードを変えて 起動するとかは...
  74. 74. Spring Cloud Contract Stub Runner
  75. 75. こんなGroovy DSLを 書いて...
  76. 76. org.springframework.cloud.contract.spec. Contract.make { request { method 'POST' url '/example' body([ "id": 12345 ]) } response { status 201 body([ "name": "john" ]) headers { contentType('application/ json;charset=UTF-8’) } }
  77. 77. スタブを配備し Stub Runnerを 起動すると...
  78. 78. $ java -jar -Dstubrunner.ids= com.jyukutyo:stub-example stub-runner.jar
  79. 79. DSLのとおりに動作する Webアプリケーションを 起動してくれる
  80. 80. $ curl -D- -X post -H 'Content-Type:application/json' -d "{"id":12345}" http://localhost:14161/example HTTP/1.1 201 Created Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Server: Jetty(9.3.16.v20170120) {"name":"john"}
  81. 81. org.springframework.cloud.contract.spec. Contract.make { request { method 'POST' url '/example' body([ "id": 12345 ]) } response { status 201 body([ "name": "john" ]) headers { contentType('application/ json;charset=UTF-8’) } }
  82. 82. これで マイクロサービスの エラー動作を 作り出せる
  83. 83. 技術的詳細
  84. 84. Spring Cloud Contract Stub Runner
  85. 85. の前に
  86. 86. Spring Cloud Contract • コンシューマ駆動契約(CDC) フレームワークの1つ • APIを使う側がほしい仕様(契約)を 書き、提供側は契約を常に満たす • 使う側: コンシューマ • 提供側: プロデューサ
  87. 87. Spring Cloud Contract • 契約をGroovy DSLで書ける • DSLからスタブを生成できる • WireMockを使ってスタブを アプリケーションとして起動する • Spring Cloud Contract WireMock
  88. 88. WireMock • HTTPベースのAPIシミュレーター http://wiremock.org/
  89. 89. 契約の使い道 • プロデューサはAPIがつねに契約を 満たすかの検証に使える • コンシューマは契約内容をスタブに してテストできる
  90. 90. そのスタブを簡単に アプリケーションとして 起動してくれるのが
  91. 91. Spring Cloud Contract Stub Runner
  92. 92. Spring Cloud Contract Stub Runner • スタブをJARにして、 Mavenリポジトリに置いておく • ローカル、インハウスでも • Stub Runnerはリポジトリから スタブをダウンロードし 適当なポートで起動する
  93. 93. Spring Cloud Contract Stub Runner • 複数のスタブも1つのStub Runner から起動できる • スタブをサービスディスカバリ (Eureka)に登録もできる https://github.com/spring-cloud/spring-cloud- contract/tree/master/spring-cloud-contract-stub-runner
  94. 94. クライ アント サービス インスタンスA サービス インスタンスB サービス インスタンスC Eureka ribbon
  95. 95. 設定変更なし! クライ アント スタブ Eureka ribbon
  96. 96. スタブをMavenリポジトリへ Artifactoryなど開発者1 MS1のスタブJAR 開発者2 MS2のスタブJAR GitでDSLを管理
  97. 97. $ mvn clean deploy/install
  98. 98. org.springframework.cloud.contract.spec. Contract.make { request { method 'POST' url '/example' body([ "id": 12345 ]) } response { status 201 body([ "name": "john" ]) headers { contentType('application/ json;charset=UTF-8’) } }
  99. 99. { "uuid" : "91053c7f-106d-4441-9dd0- b2b0fccb3388", "request" : { "url" : "/example", "method" : "POST", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.id == 12345)]" } ] }, "response" : { "status" : 201, "body" : "{"name":"john"}", "headers" : { "Content-Type" : "application/ json;charset=UTF-8” WireMockのJSON
  100. 100. Stub Runner起動 Artifactoryなど Stub Runner MS1のスタブJAR MS2のスタブJAR Eureka MS1:10001 MS2:10002
  101. 101. $ java -jar -Dstubrunner.ids=[groupId]: [artifactId],(略) -Dstubrunner.idsToServiceIds. [スタブ1のartifactId]=hoge -Dstubrunner.idsToServiceIds. [スタブ2のartifactId]=fuga stub-runner.jar Eurekaへの 登録名
  102. 102. /stubs スタブの ポート
  103. 103. Eurekaと 連携させていれば Eurekaからでも 確認できる
  104. 104. Spring Cloud Contract Verifier • テストコードでスタブを利用できる • まだ使っていないので紹介だけ
  105. 105. @RunWith(SpringRunner.class) @SpringBootTest( webEnvironment=WebEnvironment.NONE) @AutoConfigureStubRunner( ids = {"com.example:http-server- dsl:+:stubs:6565"}, workOffline = true) @DirtiesContext public class LoanApplicationServiceTests {
  106. 106. 参考: InfoQ記事 Spring Cloud Contractについて Marcin Grzejszczak氏とのQ&A https://www.infoq.com/jp/news/2017/05/spring-cloud-contract (公式翻訳: 私)
  107. 107. 展望 • 2年くらいでマイクロサービス 化が落ち着けばいいな
  108. 108. ご清聴 ありがとうございました

Hinweis der Redaktion

  • wanted to this diagram case
  • wanted to this diagram case
  • wanted to this diagram case
  • control responses from ms in test
    I‘m positive
    useful
  • control responses from ms in test
    I‘m positive
    useful
  • control responses from ms in test
    I‘m positive
    useful
  • control responses from ms in test
    I‘m positive
    useful
  • control responses from ms in test
    I‘m positive
    useful
  • run in different port from stub runner
  • control responses from ms in test
    I‘m positive
    useful

×