SlideShare uma empresa Scribd logo
1 de 68
© 2020 NTT DATA Corporation
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~
2020年12月17日
NTTデータ 技術革新統括本部
横井一輝
© 2020 NTT DATA Corporation 2
アジェンダ
モノリスからマイクロサービスへの移行(説明編)
• マイクロサービスとは
• ストラングラーパターンで段階的な移行
• 段階的に移行するための方針
モノリスからマイクロサービスへの移行(実装編)
• サービスの切り出し
• ロードバランサーによる負荷分散
• サーキットブレーカーによる障害対応
マイクロサービスへの移行戦略として、ストラングラーパターンがあります
Spring Cloud を用いた実現例を交えながら、ストラングラーパターンについて紹介します
© 2020 NTT DATA Corporation 3
自己紹介
名前: 横井一輝
所属: NTTデータ 技術革新統括本部
業務: アプリケーションのモダナイゼーション支援
趣味: ドライブ、サウナ、温泉
自己紹介
• 保守性の高いソフトウェアを構築することに興味・関心
• 現在、Spring Framework を勉強中
興味・関心
発表者近影
© 2020 NTT DATA Corporation 4
モノリスからマイクロサービスへの移行
~説明編~
© 2020 NTT DATA Corporation 5
モノリス と マイクロサービス
モノリス
DB
DB
API-Gateway
DB DB
マイクロサー
ビス
マイクロサー
ビス
マイクロサー
ビス
マイクロサー
ビス
単一の大きなシステムが
全ての業務を実行
複数の小さなサービスが
連携して業務を実行
© 2020 NTT DATA Corporation 6
モノリス と マイクロサービス のメリット・デメリット
モノリスとマイクロサービスにはそれぞれメリット・デメリットがあり、トレードオフの関係となる
モノリスの特徴
敏捷性
スケーリング
技術仕様・要件充足
パフォーマンス
データ
回復性
運用・監視
アプリケーション全体でデプロイ
全体をスケールしなければならない
個別最適不可だが技術スタックがシンプル
パフォーマンスが劣化しにくい
データの一貫性を保障しやすい
システム全体に影響する
管理の手間が少ない
組織面の一致
アーキテクチャと組織の不一致による負荷
再利用
機能を再利用する機会は従来通り
赤文字:メリット
マイクロサービスの特徴
サービスごとにデプロイ、迅速な仕様変更
サービスごとにスケーリングが可能
個別最適化可能だが技術スタック複雑化
パフォーマンスが劣化しやすい
データの一貫性が保障しにくい
サービスが隔壁となり一部の影響に留まる
管理対象が増える
アーキテクチャを組織に一致させて高効率
機能を再利用する機会を広げる
© 2020 NTT DATA Corporation 7
モノリス から マイクロサービス への移行
モノリス
DB
DB
API-Gateway
DB DB
マイクロサー
ビス
マイクロサー
ビス
マイクロサー
ビス
マイクロサー
ビス
マイクロサービスに移行する際はデメリットが顕在化しやすいため、対応が必要
技術仕様の
複雑化
性能問題 データ
整合性
運用
複雑化
© 2020 NTT DATA Corporation 8
モノリスからマイクロサービスへの移行の際に考えること
なぜ移行するのか
移行目的の明確化
代替手段の検討
成功基準の明確化
どこで分割するか
コードの分割断面
データベースの分割断面
どのサービスから分割する
か
ビジネス価値軸
分割容易性軸
モノリスと
マイクロサービスの統合
データ連携
データ整合性
【今回の発表内容】
移行方針
一度に分割か?段階的に分割か?
リスクを抑えた移行方針とは?
© 2020 NTT DATA Corporation 9
マイクロサービス移行方針
© 2020 NTT DATA Corporation 10
一度に分割するか、段階的に分割するか
一度に分割する
ビッグバンリライト
段階的に分割する
ストラングラーパターン
VS
© 2020 NTT DATA Corporation 11
ビッグバンリライト
モノリスを捨て去り、マイクロサービスへ一度に分割する方法
モダナイゼーション全般において、ビッグバンリライトはリスキーで失敗に終わる可能性が高い
DB
API-Gateway
DB DB
メッ
セージ
ユー
ザー
UI
3つの機能を
サービスとして分割
DB
単一の大きなシステム
3つの機能が存在
ユーザー メッセージ
UI
© 2020 NTT DATA Corporation 12
ストラングラーパターン
徐々にモノリスを小さくし、マイクロサービスへ段階的に分割していく方法
クライアントからのアクセスをストラングラーファサードがインターセプトし、モノリスまたは新サービスにルーティング
クライアントのアクセス先はストラングラーファサードから変わらないので、マイクロサービス移行を意識しなくてよい
新
サ
ー
ビ
ス
新
サ
ー
ビ
ス
新
サ
ー
ビ
ス
新
サ
ー
ビ
ス
ストラングラーファサー
ド
モノリス
新
サ
ー
ビ
ス
新
サ
ー
ビ
ス
ストラングラーファサー
ド
モノリス
新
サ
ー
ビ
ス
ストラングラーファサー
ド
早期切り出し あとで切り出し 切り出し完了
アクセスを
インターセプト
アクセス先は
変わらない
アクセスを
振り分ける
© 2020 NTT DATA Corporation 13
【参考】チャットアプリでのストラングラーパターン利用例
ストラングラーファサードとしてAPI Gateway を利用し、メッセージ機能から段階的にサービスとして分割していく
API-Gateway
DB
メッ
セージ
メッセージ機能以外を
モノリスに残して
サービスとしてコピー
DB
ユー
ザー
UI
Step2 Step3
DB
API-Gateway
DB DB
メッ
セージ
ユー
ザー
UI
3つの機能を
サービスとして分割
DB
単一の大きなシステム
3つの機能が存在
ユーザー メッ
セージ
UI
Step1
API-Gateway
© 2020 NTT DATA Corporation 14
ビッグバンリライト vs ストラングラーパターン
ビッグバンリライト ストラングラーパターン
メリット • 移行全体の実装コストは少ない
• 失敗のリスクを抑えられる
• 移行完了まで待たずに段階的に移行の効果
を得られる
• 移行と共に組織を成熟させられる
デメリット
• 失敗のリスクが高い
• リライトが完了するまで、効果が得られない
• ストラングラーファサードの実装コストがかかる
ユースケース
• 小規模なシステム
• 移行失敗のリスクが少ない
• 移行完了までの期間が短い
• 開発組織がマイクロサービスに成熟
• 大規模なシステム
• 移行失敗のリスクを抑えたい
• 移行完了までの期間が長い
• 開発組織がマイクロサービスに未成熟
© 2020 NTT DATA Corporation 15
ストラングラーパターンを利用して、段階的に移行する3つの方法
新機能をサービスとして実装
プレゼンテーション層とバックエンドの分離
モノリスを分解してマイクロサービスに抽出
© 2020 NTT DATA Corporation 16
方法① 新機能をサービスとして実装
メリット:新規サービスを迅速に実装できる
デメリット:既存システムを変更することが難しい
DB
API-Gateway
単一の大きなシステム
3つの機能が存在
新規サービスを実装
ユーザー メッセージ
UI
DB
ユーザー メッセージ
UI
DB
新規
サー
ビス
© 2020 NTT DATA Corporation 17
方法② プレゼンテーション層とバックエンドの分離
メリット:プレゼンテーション層とバックエンドが独立して開発ができる
デメリット:バックエンドに、大きなモノリスが残り続ける
DB
単一の大きなシステム
3つの機能が存在
ユーザー メッセージ
UI
DB
UI機能を、ユーザー・
メッセージ機能から分
離
ユーザー メッセージ
UI
© 2020 NTT DATA Corporation 18
方法③ モノリスを分解してマイクロサービスに抽出
メリット:既存システムのアーキテクチャを大幅に改善し、マイクロサービスのメリットをより多く享受できる
デメリット:他のパターンと比較して難易度が高い
API-Gateway
DB
メッ
セージ
モノリスの
メッセージ機能を抽出
DB
ユー
ザー
UI
DB
単一の大きなシステム
3つの機能が存在
ユーザー メッセージ
UI
メッ
セージ
© 2020 NTT DATA Corporation 19
ストラングラーパターンを利用して、段階的に移行する方法の比較
新機能のサービス実装
プレゼンテーション層と
バックエンドの分離
モノリスを分解して
マイクロサービスに抽出
メリット
• 新規サービスを
迅速に実装できる
• プレゼンテーション層とバックエン
ドが独立して開発ができる
• アーキテクチャを大幅に改善し、
マイクロサービスのメリットを
より多く享受できる
デメリット
• 既存システムを変更することが
難しい
• バックエンドに、大きなモノリスが
残り続ける
• 他のパターンより難易度が高い
ユースケース
• モノリスの分解は行わない
• マイクロサービスの早い段階で
の実証
• UI/UXの独立した開発・テスト
• 将来プレゼンテーション層から
マイクロサービスAPIを呼び出し
• モノリスのアーキテクチャを改善
• モノリスに実装されている機能
をマイクロサービスとして抽出
© 2020 NTT DATA Corporation 20
モノリスからマイクロサービスへの移行
~実装編~
© 2020 NTT DATA Corporation 21
マイクロサービス移行 シナリオ
とある会社で、モノリシックなチャットアプリをモダナイズするというシナリオの中で、
マイクロサービス移行に関連する設計手法や技術を説明していきます。
あと、マイクロサービス
流行ってるらしいから
検討してみて(^^)
ユーザー数増えてきたから
メッセージ送受信の
キャパを向上させて欲しい
マイクロサービス?
ナニそれ?
オイシイの?
© 2020 NTT DATA Corporation 22
チャットアプリの現行アーキテクチャ
開発言語:Java
フレームワーク:Spring Boot
データベース:HSQL
実装機能:
1. UI
2. ユーザー管理機能
3. メッセージ管理機能
DB
ユーザー メッセージ
UI
Spring Boot
メッセージ管理機能の
スケーラビリティ向上が
マイクロサービス移行の目的
こちらのチャットアプリをサンプルアプリとして、マイクロサービス移行の検証を行なっていきます
© 2020 NTT DATA Corporation 23
新機能のサービス実装
プレゼンテーション層と
バックエンドの分離
モノリスを分解して
マイクロサービスに抽出
メリット
• 新規サービスを
迅速に実装できる
• プレゼンテーション層とバックエン
ドが独立して開発ができる
• アーキテクチャを大幅に改善し、
マイクロサービスのメリットを
より多く享受できる
デメリット
• 既存システムを変更することが
難しい
• バックエンドに、大きなモノリスが
残り続ける
• 他のパターンより難易度が高い
ユースケース
• モノリスの分解は行わない
• マイクロサービスの早い段階で
の実証
• UI/UXの独立した開発・テスト
• 将来プレゼンテーション層から
マイクロサービスAPIを呼び出し
• モノリスのアーキテクチャを改善
• モノリスに実装されている機能
をマイクロサービスとして抽出
今回採用したストラングラーパターン
メッセージ管理機能
を改善したいので選択
© 2020 NTT DATA Corporation 24
マイクロサービス 移行手順
最初に、ストラングラーパターンでマイクロサービスの切り出しを行う
その後、ロードバランサーやサーキットブレーカーを実装し、よりクラウドネイティブにシフトしていく
DB
ユー
ザー
メッ
セージ
UI
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
ストラングラーパターン
によるサービス切り出し
ロードバランサによる
負荷分散
サーキットブレーカによる
障害対応
メッ
セージ
メッ
セージ
© 2020 NTT DATA Corporation 25
ストラングラーパターンによるサービス切り出し
© 2020 NTT DATA Corporation 26
ストラングラーパターンによるサービス切り出し
DB
API-Gateway
DB
メッ
セージ
ユーザー メッ
セージ
UI
DB
ユー
ザー
UI
ストラングラーパターンを使って、メッセージサービスを安全に切り出し
Spring Cloud Gatewayを利用してAPI ゲートウェイを実装
ストラングラーパターン
でメッセージサービス
に切り出し
メッセージ機能を
安全に切り出して
スケーラビリティ
向上させたい
© 2020 NTT DATA Corporation 27
Spring Cloud Gateway とは
• 様々な要素でルーティングルールを設定
• URLパス
• ヘッダーやクッキーの値
• メソッド(GET、POSTなど)
• 時間(〇時以前、以降など)
• リクエスト、レスポンスの内容をフィルターで書き換え
• サーキットブレーカー、サービスディスカバリ、セキュリティの機能との統合も可能
• 類似のライブラリ Spring Cloud Netflix Zuul はメンテナンスモードに移行
現在は Spring Cloud Gateway の使用が推奨されてる
API ゲートウェイ を構築するための、シンプルかつ柔軟な ライブラリ
今回の検証バージョン
Spring Boot 2.3.5, Spring Cloud Hoxton.SR8
© 2020 NTT DATA Corporation 28
Step 1. ストラングラーファサードの実装
1. ストラングラーファサードの実装
2. モノリスからマイクロサービスへの
抽出(AP)
3. モノリスからマイクロサービスへの
抽出(DB)
4. ストラングラーファサードの呼び出し
先の書き換え
5. 認証情報の連携
API-Gateway
DB
ユーザー メッセージ
UI
localhost:8080
localhost:8081
Spring Cloud
Gateway
Spring Boot
© 2020 NTT DATA Corporation 29
ストラングラーファサードの実装
1. Spring Initializr から Spring Cloud Gateway を依存関係に追加したアプリケーションを作成
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Mavenを利用する場合
pom.xml に追記
Gateway を追加
© 2020 NTT DATA Corporation 30
ストラングラーファサードの実装
2. RouteLocator の Bean を作成し、ルーティングルールを設定
@SpringBootApplication
public class Application {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p.path("/**")
.uri("http://localhost:8081")
)
.build();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
パスのパターンマッチにアスタリスクで全マッチ
全リクエストをモノリス(localhost:8081)に転送
Java config の場合
(yaml で記述することも可能)
© 2020 NTT DATA Corporation 31
Step 1. ストラングラーファサードの実装 の課題
■課題
Logout実行時、リダイレクト先を示す
Locationヘッダーが
:8081/login で帰ってくるため
正しくページ遷移しない
■アプローチ
API Gatewayにて、
Location ヘッダーの値を書き換える
必要がある
API-Gateway
DB
ユーザー メッセージ
UI
localhost:8080
localhost:8081
:8081/Logout
:8080/Logout
Location :8081/Login
Location :8081/Login ×
Location :8080/Login ○
© 2020 NTT DATA Corporation 32
レスポンスの Location ヘッダーの値を書き換え(実装)
return builder.routes()
.route(p - > p
.path("/**")
.filters(f - > f
.rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "localhost:8080", "http"))
.uri("http://localhost:8081")
)
.build();
レスポンスヘッダーに Location が存在する場合は
フィルターでホスト名を localhost:8080 に書き換え
© 2020 NTT DATA Corporation 33
Step 2. モノリスからマイクロサービスへの抽出(AP)
1. ストラングラーファサードの実装
2. モノリスからマイクロサービスへの
抽出(AP)
3. モノリスからマイクロサービスへの
抽出(DB)
4. ストラングラーファサードの呼び出し
先の書き換え
5. 認証情報の連携
localhost:8080
localhost:8081
API-Gateway
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
localhost:8082
Spring Boot
© 2020 NTT DATA Corporation 34
Step 2. モノリスからマイクロサービスへの抽出(AP)の課題
■課題
共通ライブラリの存在や
他機能と密結合しているなどで、
メッセージサービスだけをきれいに
抽出することが困難
■解決策
メッセージサービスだけを
抽出しようとせずに、
大きめにサービスを抽出してから、
不要なコードを削ぎ落としていく
localhost:8080
localhost:8081
DB
ユー
ザー
UI
メッ
セージ
localhost:8082
Spring Boot
ユー
ザー
UI
ユー
ザー
UI
メッ
セージ
API-Gateway
© 2020 NTT DATA Corporation 35
Step 3. モノリスからマイクロサービスへの抽出(DB)
1. ストラングラーファサードの実装
2. モノリスからマイクロサービスへの
抽出(AP)
3. モノリスからマイクロサービスへの
抽出(DB)
4. ストラングラーファサードの呼び出し
先の書き換え
5. 認証情報の連携
localhost:8080
localhost:8081
API-Gateway
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
Spring Boot
localhost:8082
ユー
ザー
メッ
セージ
メッ
セージ
メッ
セージ
© 2020 NTT DATA Corporation 36
Step 3. モノリスからマイクロサービスへの抽出(DB) の課題
■課題
以下の場合、モノリスとマイクロサービス
のデータ連携を設計する必要がある
• 切り出すAPとモノリスに残るAPが
同一のテーブルにアクセス
• 切り出すテーブルとモノリスに残る
テーブルが、外部結合している
(今回のパターン)
■解決策の選択肢
• モノリスAPを通して
モノリスDBのデータを参照
• モノリスDBに
マイクロサービスAPが直接参照
• モノリスDB更新をトリガーに
マイクロサービスDBに更新を反映
DB
ユー
ザー
UI
メッ
セージ
API-Gateway
DB
メッ
セージ
Spring Boot
ユーザー情報
更新リクエスト
ユーザー
テーブル更新
ユー
ザー
メッ
セージ
最新のユーザー情報
はどこ?
© 2020 NTT DATA Corporation 37
モノリスからマイクロサービスへのデータ連携の解決策
API-Gateway
メッ
セージ
ユー
ザー
UI
API-Gateway
メッ
セージ
ユー
ザー
UI
API-Gateway
メッ
セージ
ユー
ザー
UI
ユー
ザー
ユー
ザー
ユー
ザー
メッ
セージ
メッ
セージ
メッ
セージ
ユー
ザー
モノリスAPを通して
モノリスDBのデータを参照
モノリスDBに
マイクロサービスAPが直接参照
モノリスDB更新をトリガーに
マイクロサービスDBに更新を反映
メリット:
サービスの疎結合が保たれる
デメリット:
モノリスAPの修正が必要
メリット:
実装コストが低い
デメリット:
モノリスDBと密結合になる
メリット:
サービスの疎結合が保たれる
デメリット:
更新反映用の部品が必要
参照 更新
© 2020 NTT DATA Corporation 38
Step 4. ストラングラーファサードの呼び出し先の書き換え
1. ストラングラーファサードの実装
2. モノリスからマイクロサービスへの
抽出(AP)
3. モノリスからマイクロサービスへの
抽出(DB)
4. ストラングラーファサードの呼び出
し先の書き換え
5. 認証情報の連携
localhost:8080
localhost:8081
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
localhost:8082
UI・ユーザー機能 メッセージサービス
DB
メッ
セージ
© 2020 NTT DATA Corporation 39
Step 4. ストラングラーファサードの呼び出し先の書き換え の課題
■課題の背景
STOMP というメッセージングプロトコル
(WebSocket通信の一種)
を利用して、チャットの送受信を実装
■課題
WebSocket通信とHTTP通信の
通信プロトコルの違いによる
ルーティング設定ができない
■解決法
STOMPプロトコルに沿った
URLパスベースのルーティングを
設定する必要がある
STOMPのメッセージフロー
© 2020 NTT DATA Corporation 40
STOMP プロトコルに沿った 切り出し先サービスへのルーティング設定(実装)
return builder.routes()
.route(p - > p
.path("/chat/messages").or().path("/messages/**")
.uri("http://localhost:8082"))
.route(p - > p
.path("/topic/**").or().path("/chat/messages/{segment}/**")
.uri("ws://localhost:8082"))
.route(p - > p
.path("/**")
.filters(f - > f
.rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "localhost:8080", "http"))
.uri("http://localhost:8081"))
.build();
WebSocket 通信用の
ルーティング設定
http通信用の
ルーティング設定
© 2020 NTT DATA Corporation 41
Step.5 認証情報の連携
1. ストラングラーファサードの実装
2. モノリスからマイクロサービスへの
抽出(AP)
3. モノリスからマイクロサービスへの
抽出(DB)
4. ストラングラーファサードの呼び出し
先の書き換え
5. 認証情報の連携
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
DB
メッ
セージ
太郎さんが
ログイン
太郎さんが
メッセージ送信
太郎さんを
認証 メッセージ送信
したのは誰?
© 2020 NTT DATA Corporation 42
Step.5 認証情報の連携の課題
■課題
モノリシックなシステムでは
セッション認証を採用していた。
しかし、切り出し先のマイクロサービスは
モノリシックが認証した情報を
知ることができない。
■解決策の選択肢
• 単純なBasic 認証
• JWTを使ったトークン認証 ← 採用
• OAuth 2.0 認証・認可
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
DB
メッ
セージ
セッション認証
認証情報をどう
連携するのか?
© 2020 NTT DATA Corporation 43
JWTを
返却
Step.5 認証情報の連携(アクセストークン認証)
1. ユーザーIDとパスワードを入力して
ログインリクエストを送る
2. モノリスにログインリクエストを
ルーティングする
3. モノリスが JWT トークンを
クッキーに入れて返却
4. メッセージサービスを呼び出すとき
JWT トークンをクッキーに含む
リクエストを送る
5. APIゲートウェイが JWT トークンを
Authorizationヘッダーに
組み込む
6. メッセージサービスが
JWT トークンを検証
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
DB
メッ
セージ
①
②
④
⑤
⑥
IDとPWで
ログイン
IDとPWで
ログイン
JWTをクッキー
に与える
JWTを認可ヘッダー
に与える
JWTを
検証
③
© 2020 NTT DATA Corporation 44
認証情報の連携(実装)
return builder.routes()
.route(p - > p
.path("/chat/messages").or().path("/messages/**")
.filters(f - > f
.filter(preGatewayFilterFactory.apply(new Config()))
.uri("http://localhost:8082"))
.route(p - > p
.path("/topic/**").or().path("/chat/messages/{segment}/**")
.filters(f - > f
.filter(filter(preGatewayFilterFactory.apply(new Config()))
.uri("ws://localhost:8082"))
.route(p - > p
.path("/**")
.filters(f - > f
.rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "localhost:8080", "http"))
.uri("http://localhost:8081"))
.build();
ゲートウェイ フィルタ を自作し
リクエストやレスポンスの中身を
自由自在に書き換え可能
© 2020 NTT DATA Corporation 45
認証情報の連携(実装)
public class PreGatewayFilterFactory
extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
(中略)
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
Optional<HttpCookie> token =
Optional.ofNullable(exchange.getRequest().getCookies().getFirst("USERINFO"));
if (token.isEmpty())
return chain.filter(exchange);
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
builder.headers((httpHeaders) -> {
httpHeaders.set("Authorization", token.get().getValue());
});
return chain.filter(exchange.mutate().request(builder.build()).build());
};
}
(中略)
}
Authorization ヘッダーに
アクセストークンを付与
Cookie 情報から
アクセストークンを取得
自作した ゲートウェイ フィルタ
© 2020 NTT DATA Corporation 46
マイクロサービス移行 シナリオ ~途中経過~
マイクロサービス移行の第一段階を終え、メッセージ管理機能の切り離しに成功。
当初の「メッセージ管理機能の性能向上」の目的を果たすため、引き続きマイクロサービス移行を実施する。
ところで、
メッセージ機能の性能は
向上したのかね??
マイクロサービス移行。
ご苦労だった。
できたー!
マイクロサービス
完全に理解!!
性能向上の目的
を忘れてた……
© 2020 NTT DATA Corporation 47
ロードバランサーによる負荷分散
© 2020 NTT DATA Corporation 48
ロードバランサーによる負荷分散
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
メッ
セージ
ロードバランサーを使って、アクセスの負荷を分散
Spring Cloud LoadBalancer と Spring Cloud Netflix Eureka を利用
メッセージサービスを
多重化して
ロードバランサーで
負荷分散
アクセス集中時の
メッセージサービスへの
負荷を分散したい
© 2020 NTT DATA Corporation 49
Spring Cloud LoadBalancer と Spring Cloud Netflix Eureka とは
Spring Cloud LoadBalancer
• ロードバランサーを構築するためのライブラリ
• メンテナンスモードに移行した Netflix Ribbon の代わりに使用が推奨
• Ribbon で行っていた作業を抽象化して提供されている
Spring Cloud Netflix Eureka
• Netflix 社製のサービスディスカバリ用のサービスレジストリとクライアントを構築するライブラリ
• サービスディスカバリを利用することで、DNSのようにサービス名からIPアドレス取得することが可能
• Eureka はメンテナンスモードへの移行はいまのところ宣言されていない
ロードバランサーとサービスディスカバリを Spring で構築するためのライブラリ
今回の検証バージョン
Spring Boot 2.3.5, Spring Cloud Hoxton.SR8
© 2020 NTT DATA Corporation 50
Step 1. Eureka サービスレジストリ の作成・起動
1. Eureka サービスレジストリを
作成・起動
2. クライアントを
サービスレジストリに登録
3. サービス一覧を取得し、
リクエストをロードバランサーで分散
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
DB
メッ
セージ
サービス
レジストリ
メッ
セージ
サービス名 アドレス
①起動
© 2020 NTT DATA Corporation 51
Eureka サービスレジストリ の作成・起動(実装)
1. Spring Initializr から Eureka Server を依存関係に追加した アプリケーションを作成
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Mavenを利用する場合
Eureka サービスレジストリの
依存関係をpom.xml に追記
Eureka Server
を追加
© 2020 NTT DATA Corporation 52
Eureka サービスレジストリ の作成・起動(実装)
2. テスト用の設定を application.properties に追記
3. サービスレジストリを有効にするためアノテーション “@EnableEurekaServer” を追加
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Eureka サービスレジストリの
アプリケーションクラスに
@EnableEurekaServer
を追加
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
テスト用の単純目的のため
自分自身の登録を無効化
© 2020 NTT DATA Corporation 53
Step 2. サービスレジストリに登録
1. Eureka サービスレジストリを
作成・起動
2. クライアントを
サービスレジストリに登録
3. サービス一覧を取得し、
リクエストをロードバランサーで分散
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
DB
メッ
セージ
サービス
レジストリ
メッ
セージ
②登録
①起動
サービス名 アドレス
サービス名 アドレス
message localhost:8082
localhost:8083
© 2020 NTT DATA Corporation 54
サービスレジストリに登録(実装)
1. メッセージサービスに Eureka Discovery Client の依存関係を追加
2. サービスレジストリに登録するためのアノテーション “@EnableDiscoveryClient” を追加
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
@EnableDiscoveryClient
@SpringBootApplication
public class MessageApplication {
public static void main(String[] args) {
SpringApplication.run(MessageApplication.class, args);
}
}
メッセージサービスの
pom.xml に依存関係を追記
メッセージサービスの
アプリケーションクラスに
@EnableDiscoveryClient
を追加
© 2020 NTT DATA Corporation 55
サービスレジストリに登録(実装)
3. サービスレジストリに登録するサービス名を application.properties に設定
4. 同じサービス名で複数起動することで、多重度が上がる
server.port=8082
spring.application.name=message
サービス名を設定
server.port=8082
spring.application.name=message
server.port=8083
spring.application.name=message
メッセージサービス①
用のプロパティ
メッセージサービス②
用のプロパティ
© 2020 NTT DATA Corporation 56
Step 3.サービス一覧を取得し、リクエストをロードバランサで分散
1. Eureka サービスレジストリを
作成・起動
2. クライアントを
サービスレジストリに登録
3. サービス一覧を取得し、
リクエストをロードバランサで分散
API-Gateway
DB
ユー
ザー
UI
メッ
セージ
DB
メッ
セージ
サービス
レジストリ
メッ
セージ
②登録
①起動
③リクエスト分散
③サービス一覧を取得
サービス名 アドレス
message localhost:8082
localhost:8083
© 2020 NTT DATA Corporation 57
サービス一覧を取得し、リクエストをロードバランサで分散(実装)
1. Spring Cloud Gateway に Eureka Discovery Client の依存関係を追加
2. Spring Cloud Gateway の application.properties に設定
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.loadbalancer.ribbon.enabled=false
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Spring Cloud Gatewayの
pom.xml に
依存関係を追記
サービスディスカバリを有効化して
サービス一覧を取得する設定
Netflix Ribbon を無効化し
Spring Cloud LoadBalancer を
有効化するための設定
© 2020 NTT DATA Corporation 58
API ゲートウェイからのアクセスをロードバランサで振り分け(実装)
3. Spring Cloud Gateway の RouteLocator の Bean を修正しロードバランシングできるように設定
return builder.routes()
.route(p - > p
.path("/chat/messages").or().path("/messages/**")
.uri("lb://message"))
.route(p - > p
.path("/topic/**").or().path("/chat/messages/{segment}/**")
.uri("lb:ws://message"))
`lb://[サービス名]` と記述することで
ロードバランサを利用可能
http://localhost:8082
→ lb://message
WebSocket通信の際は
`lb:ws://[サービス名]` と記述する
ws://localhost:8082
→ lb:ws://message
© 2020 NTT DATA Corporation 59
サーキットブレーカーによる障害対応
© 2020 NTT DATA Corporation 60
サーキットブレーカーによる障害対応
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
メッ
セージ
API-Gateway
DB
メッ
セージ
DB
ユー
ザー
UI
メッ
セージ
メッ
セージ
サーキットブレーカーを使って、サーバー高負荷時はアクセスを一時遮断
Spring Cloud Circuit Breaker と Resilience4J を利用
サーバーレスポンスが
遅い場合は
アクセスを一時遮断
サーバー高負荷時に
サーバーレスポンスが
遅い場合も
アクセスは止まらない
© 2020 NTT DATA Corporation 61
Spring Cloud Circuit breaker とは
• メンテナンスモードに移行した Netflix Hystrix の代わりに使用が推奨
• さまざまなサーキットブレーカーの実装にわたって抽象化を提供されており、
開発者はアプリケーションのニーズに最適なサーキットブレーカーを選択可能
• 下記のサーキットブレーカーと組み合わせて使用可能
• Hystrix
• Resilience4J
• リアクティブ Resilience4J ← 今回使用
• Spring Retry
• Sentinal
サーキットブレーカーを Spring で構築するためのライブラリ
今回の検証バージョン
Spring Boot 2.3.5, Spring Cloud Hoxton.SR8
© 2020 NTT DATA Corporation 62
サーキットブレーカによる障害対応(実装)
1. Spring Cloud Gateway に Resilience4j の依存関係を追加
2. Spring Cloud Gate に Resilience4j の設定を修正する Bean を追記
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
Spring Cloud Gatewayの
pom.xml に追記
@Bean
public Customizer <ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
return factory - > factory
.configureDefault(id - > new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.timeLimiterConfig(TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(4)).build())
.build());
} 4秒以内にレスポンスがない場合
サーキットブレーカーが発動する設定
© 2020 NTT DATA Corporation 63
サーキットブレーカによる障害対応(実装)
3. Spring Cloud Gateway の RouteLocator にサーキットブレーカーフィルターを追加
4. Spring Cloud Gateway に アクセス遮断時の既定レスポンスを実装
.route(p -> p.path(“/chat/messages”).or().path(“/messages/**”)
.filters(f -> f
.circuitBreaker(c -> c.setFallbackUri("forward:/fallback")))
.uri("lb://message"))
@RequestMapping("/fallback")
public Mono<String> fallback () {
return Mono.just("You can't access message service...");
}
アクセス遮断時に呼ばれる
URIを設定
アクセス遮断時の
既定レスポンス
© 2020 NTT DATA Corporation 64
まとめ
© 2020 NTT DATA Corporation 65
マイクロサービス移行 シナリオ ~エピローグ ~
マイクロサービス移行を終え、メッセージ管理機能の切り離しと、負荷分散・障害対応を実施。
マイクロサービス・リーダーに任命され、引き続きマイクロサービス移行を担当していくことに。
君を
マイクロサービス・リーダー
に任命する。
今度こそ
マイクロサービス移行。
ご苦労だった。
やったー!
マイクロサービス
リーダーだ!!
© 2020 NTT DATA Corporation 66
まとめ
モノリスを分割することで、ミドルウェアが隠ぺいしていたことの再設計が必要になる
段階的に移行する方針は、設計漏れを早期に発見できる点で、リスクを下げて移行できる
今後は分割断面の見つけ方や、モノリスとマイクロサービス間のデータ連携について検証していきたい
また、今回は Spring Cloud を用いてロードバランサやサーキットブレーカを実装した
しかしこれらは、Istio などのサービスメッシュや AWS などのクラウドサービスでも同様のことができる
今後、これらとの比較検証も行っていきたい
気づき
• リスクをさげてマイクロサービスに移行する戦略として、ストラングラーパターンの紹介
• マイクロサービスに移行するためのデモンストレーション
• ストラングラーパターンの実装
• ロードバランサの実装
• サーキットブレーカを実装
まとめ
© 2020 NTT DATA Corporation 67
参考情報
Spring I/O 2018 報告会 - Spring Cloud Gateway / Spring Cloud Pipelines
https://www.slideshare.net/JunyaKatada/spring-io-2018-spring-cloud-gateway-spring-
cloud-pipelines
ぱぱっと理解するSpring Cloudの基本
https://www.slideshare.net/kazukikumagai1/spring-cloud
Introducing Spring Cloud Gateway by Spencer Gibb @ Spring I/O 2018
https://www.youtube.com/watch?v=NkgooKSeF8w
Monolith to Microservice デモアプリ
https://github.com/spencergibb/monolith-to-microservices
© 2020 NTT DATA Corporation
本資料に記載されている会社名、商品名、又はサービス名は、各社の登録商標又は商標です。

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Azure API Management 俺的マニュアル
Azure API Management 俺的マニュアルAzure API Management 俺的マニュアル
Azure API Management 俺的マニュアル
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
 
マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜
 
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
 
なぜ「マイクロサービス“化”」が必要なのか
なぜ「マイクロサービス“化”」が必要なのかなぜ「マイクロサービス“化”」が必要なのか
なぜ「マイクロサービス“化”」が必要なのか
 
マルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのことマルチテナント化で知っておきたいデータベースのこと
マルチテナント化で知っておきたいデータベースのこと
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方
 
3分でわかるAzureでのService Principal
3分でわかるAzureでのService Principal3分でわかるAzureでのService Principal
3分でわかるAzureでのService Principal
 
Serverless時代のJavaについて
Serverless時代のJavaについてServerless時代のJavaについて
Serverless時代のJavaについて
 
Keycloak入門
Keycloak入門Keycloak入門
Keycloak入門
 
マイクロサービスに至る歴史とこれから - XP祭り2021
マイクロサービスに至る歴史とこれから - XP祭り2021マイクロサービスに至る歴史とこれから - XP祭り2021
マイクロサービスに至る歴史とこれから - XP祭り2021
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
 
マイクロサービス化デザインパターン - #AWSDevDay Tokyo 2018
マイクロサービス化デザインパターン - #AWSDevDay Tokyo 2018マイクロサービス化デザインパターン - #AWSDevDay Tokyo 2018
マイクロサービス化デザインパターン - #AWSDevDay Tokyo 2018
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
 

Semelhante a モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)

M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]
M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]
M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]
日本マイクロソフト株式会社
 
日米クラウド最前線!経営戦略としてのクラウドを考える
日米クラウド最前線!経営戦略としてのクラウドを考える日米クラウド最前線!経営戦略としてのクラウドを考える
日米クラウド最前線!経営戦略としてのクラウドを考える
Nissho-Blocks
 

Semelhante a モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料) (20)

TOUA M2M Solutions powered by Cloudian (Cloudian Summit 2012)
TOUA M2M Solutions powered by Cloudian (Cloudian Summit 2012)TOUA M2M Solutions powered by Cloudian (Cloudian Summit 2012)
TOUA M2M Solutions powered by Cloudian (Cloudian Summit 2012)
 
プロセスマイニングとソースコード解析を用いたマイクロサービス分割(ソフトウェアエンジニアリングシンポジウム2021 発表資料)
プロセスマイニングとソースコード解析を用いたマイクロサービス分割(ソフトウェアエンジニアリングシンポジウム2021 発表資料)プロセスマイニングとソースコード解析を用いたマイクロサービス分割(ソフトウェアエンジニアリングシンポジウム2021 発表資料)
プロセスマイニングとソースコード解析を用いたマイクロサービス分割(ソフトウェアエンジニアリングシンポジウム2021 発表資料)
 
オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)
オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)
オンプレミスからクラウドへ:Oracle Databaseの移行ベストプラクティスを解説 (Oracle Cloudウェビナーシリーズ: 2021年2月18日)
 
[Cloud OnAir] Next ’19 サンフランシスコ最新情報 GCP 特集 2019年4月11日 放送
[Cloud OnAir] Next ’19 サンフランシスコ最新情報 GCP 特集 2019年4月11日 放送[Cloud OnAir] Next ’19 サンフランシスコ最新情報 GCP 特集 2019年4月11日 放送
[Cloud OnAir] Next ’19 サンフランシスコ最新情報 GCP 特集 2019年4月11日 放送
 
Cloudflareのソリューションを使用して悪意のあるBot対策
Cloudflareのソリューションを使用して悪意のあるBot対策Cloudflareのソリューションを使用して悪意のあるBot対策
Cloudflareのソリューションを使用して悪意のあるBot対策
 
マイクロサービスのセキュリティ概説
マイクロサービスのセキュリティ概説マイクロサービスのセキュリティ概説
マイクロサービスのセキュリティ概説
 
CCGrid2012 参加報告
CCGrid2012 参加報告CCGrid2012 参加報告
CCGrid2012 参加報告
 
LTEモバイルクラウドセミナ[講演1] R 20101116
LTEモバイルクラウドセミナ[講演1] R 20101116LTEモバイルクラウドセミナ[講演1] R 20101116
LTEモバイルクラウドセミナ[講演1] R 20101116
 
クラウド検討の進め方
クラウド検討の進め方クラウド検討の進め方
クラウド検討の進め方
 
「小さくはじめる→成功する→全体最適へ→成功する」が黄金ルール
「小さくはじめる→成功する→全体最適へ→成功する」が黄金ルール「小さくはじめる→成功する→全体最適へ→成功する」が黄金ルール
「小さくはじめる→成功する→全体最適へ→成功する」が黄金ルール
 
Mk data intensive-onic2021
Mk data intensive-onic2021Mk data intensive-onic2021
Mk data intensive-onic2021
 
仮想化時代のBCP 今できることと将来できること
仮想化時代のBCP 今できることと将来できること仮想化時代のBCP 今できることと将来できること
仮想化時代のBCP 今できることと将来できること
 
機密データとSaaSは共存しうるのか!?セキュリティー重視のユーザー層を取り込む為のネットワーク通信のアプローチ
機密データとSaaSは共存しうるのか!?セキュリティー重視のユーザー層を取り込む為のネットワーク通信のアプローチ機密データとSaaSは共存しうるのか!?セキュリティー重視のユーザー層を取り込む為のネットワーク通信のアプローチ
機密データとSaaSは共存しうるのか!?セキュリティー重視のユーザー層を取り込む為のネットワーク通信のアプローチ
 
CSP パートナー向け向け Azure マネージド サービス プレイブック
CSP パートナー向け向け Azure マネージド サービス プレイブックCSP パートナー向け向け Azure マネージド サービス プレイブック
CSP パートナー向け向け Azure マネージド サービス プレイブック
 
M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]
M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]
M17_情シス必見、Azure Arc によるマルチプラットフォーム管理の今 [Microsoft Japan Digital Days]
 
Circle of Code with Cloud Foundry
Circle of Code with Cloud FoundryCircle of Code with Cloud Foundry
Circle of Code with Cloud Foundry
 
【HinemosWorld2014】A1-3_01_NTT Comのグローバルクラウド戦略とHinemosとの連携について
【HinemosWorld2014】A1-3_01_NTT Comのグローバルクラウド戦略とHinemosとの連携について【HinemosWorld2014】A1-3_01_NTT Comのグローバルクラウド戦略とHinemosとの連携について
【HinemosWorld2014】A1-3_01_NTT Comのグローバルクラウド戦略とHinemosとの連携について
 
日米クラウド最前線!経営戦略としてのクラウドを考える
日米クラウド最前線!経営戦略としてのクラウドを考える日米クラウド最前線!経営戦略としてのクラウドを考える
日米クラウド最前線!経営戦略としてのクラウドを考える
 
Aws summit tokyo 2016
Aws summit tokyo 2016Aws summit tokyo 2016
Aws summit tokyo 2016
 
Nttドコモ事例から見るモバイル&クラウド時代のサービス開発についてr4(public)
Nttドコモ事例から見るモバイル&クラウド時代のサービス開発についてr4(public)Nttドコモ事例から見るモバイル&クラウド時代のサービス開発についてr4(public)
Nttドコモ事例から見るモバイル&クラウド時代のサービス開発についてr4(public)
 

Mais de NTT DATA Technology & Innovation

Mais de NTT DATA Technology & Innovation (20)

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
OSSデータベースの開発コミュニティに参加しよう! (DEIM2024 発表資料)
OSSデータベースの開発コミュニティに参加しよう! (DEIM2024 発表資料)OSSデータベースの開発コミュニティに参加しよう! (DEIM2024 発表資料)
OSSデータベースの開発コミュニティに参加しよう! (DEIM2024 発表資料)
 
COPY FROMで異常データをスキップできるようになった話(第45回 PostgreSQLアンカンファレンス@オンライン 発表資料)
COPY FROMで異常データをスキップできるようになった話(第45回 PostgreSQLアンカンファレンス@オンライン 発表資料)COPY FROMで異常データをスキップできるようになった話(第45回 PostgreSQLアンカンファレンス@オンライン 発表資料)
COPY FROMで異常データをスキップできるようになった話(第45回 PostgreSQLアンカンファレンス@オンライン 発表資料)
 
Cloud Skills Challenge 2023 winter 〜Azureを頑張る理由と頑張り方
Cloud Skills Challenge 2023 winter 〜Azureを頑張る理由と頑張り方Cloud Skills Challenge 2023 winter 〜Azureを頑張る理由と頑張り方
Cloud Skills Challenge 2023 winter 〜Azureを頑張る理由と頑張り方
 
Unlocking Transformation: Implementing GitOps Practices in Conservative Organ...
Unlocking Transformation: Implementing GitOps Practices in Conservative Organ...Unlocking Transformation: Implementing GitOps Practices in Conservative Organ...
Unlocking Transformation: Implementing GitOps Practices in Conservative Organ...
 
Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)
Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)
Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)
 
詳説探究!Cloud Native Databaseの現在地点(CloudNative Days Tokyo 2023 発表資料)
詳説探究!Cloud Native Databaseの現在地点(CloudNative Days Tokyo 2023 発表資料)詳説探究!Cloud Native Databaseの現在地点(CloudNative Days Tokyo 2023 発表資料)
詳説探究!Cloud Native Databaseの現在地点(CloudNative Days Tokyo 2023 発表資料)
 
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
 
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
 
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
 
マネージドPostgreSQLの実現に向けたPostgreSQL機能向上(PostgreSQL Conference Japan 2023 発表資料)
マネージドPostgreSQLの実現に向けたPostgreSQL機能向上(PostgreSQL Conference Japan 2023 発表資料)マネージドPostgreSQLの実現に向けたPostgreSQL機能向上(PostgreSQL Conference Japan 2023 発表資料)
マネージドPostgreSQLの実現に向けたPostgreSQL機能向上(PostgreSQL Conference Japan 2023 発表資料)
 
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
 
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(Open Source Conference 202...
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(Open Source Conference 202...PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(Open Source Conference 202...
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(Open Source Conference 202...
 
骨抜きアジャイルの骨を生み出す 〜私(スクラムマスター)のXP学習記録〜(XP祭り2023 発表資料)
骨抜きアジャイルの骨を生み出す 〜私(スクラムマスター)のXP学習記録〜(XP祭り2023 発表資料)骨抜きアジャイルの骨を生み出す 〜私(スクラムマスター)のXP学習記録〜(XP祭り2023 発表資料)
骨抜きアジャイルの骨を生み出す 〜私(スクラムマスター)のXP学習記録〜(XP祭り2023 発表資料)
 
機械学習モデルを REST API としてサービングするシステム開発における上流プロセスの絞り込みと効果検証(PM学会2023年度秋季研究発表大会 発表資料)
機械学習モデルを REST API としてサービングするシステム開発における上流プロセスの絞り込みと効果検証(PM学会2023年度秋季研究発表大会 発表資料)機械学習モデルを REST API としてサービングするシステム開発における上流プロセスの絞り込みと効果検証(PM学会2023年度秋季研究発表大会 発表資料)
機械学習モデルを REST API としてサービングするシステム開発における上流プロセスの絞り込みと効果検証(PM学会2023年度秋季研究発表大会 発表資料)
 
ChatGPTのデータソースにPostgreSQLを使う[詳細版](オープンデベロッパーズカンファレンス2023 発表資料)
ChatGPTのデータソースにPostgreSQLを使う[詳細版](オープンデベロッパーズカンファレンス2023 発表資料)ChatGPTのデータソースにPostgreSQLを使う[詳細版](オープンデベロッパーズカンファレンス2023 発表資料)
ChatGPTのデータソースにPostgreSQLを使う[詳細版](オープンデベロッパーズカンファレンス2023 発表資料)
 
PostgreSQL on Kubernetes: Realizing High Availability with PGO (Postgres Ibiz...
PostgreSQL on Kubernetes: Realizing High Availability with PGO (Postgres Ibiz...PostgreSQL on Kubernetes: Realizing High Availability with PGO (Postgres Ibiz...
PostgreSQL on Kubernetes: Realizing High Availability with PGO (Postgres Ibiz...
 
オンプレミス回帰の動きに備えよ ~クラウドの手法をオンプレミスでも実現するには~(CloudNative Days Fukuoka 2023 発表資料)
オンプレミス回帰の動きに備えよ ~クラウドの手法をオンプレミスでも実現するには~(CloudNative Days Fukuoka 2023 発表資料)オンプレミス回帰の動きに備えよ ~クラウドの手法をオンプレミスでも実現するには~(CloudNative Days Fukuoka 2023 発表資料)
オンプレミス回帰の動きに備えよ ~クラウドの手法をオンプレミスでも実現するには~(CloudNative Days Fukuoka 2023 発表資料)
 
Prometheus Operator 入門(Kubernetes Novice Tokyo #26 発表資料)
Prometheus Operator 入門(Kubernetes Novice Tokyo #26 発表資料)Prometheus Operator 入門(Kubernetes Novice Tokyo #26 発表資料)
Prometheus Operator 入門(Kubernetes Novice Tokyo #26 発表資料)
 
ChatGPTのデータソースにPostgreSQLを使う(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
ChatGPTのデータソースにPostgreSQLを使う(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)ChatGPTのデータソースにPostgreSQLを使う(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
ChatGPTのデータソースにPostgreSQLを使う(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
 

Último

Último (11)

論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 

モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)

  • 1. © 2020 NTT DATA Corporation モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~ 2020年12月17日 NTTデータ 技術革新統括本部 横井一輝
  • 2. © 2020 NTT DATA Corporation 2 アジェンダ モノリスからマイクロサービスへの移行(説明編) • マイクロサービスとは • ストラングラーパターンで段階的な移行 • 段階的に移行するための方針 モノリスからマイクロサービスへの移行(実装編) • サービスの切り出し • ロードバランサーによる負荷分散 • サーキットブレーカーによる障害対応 マイクロサービスへの移行戦略として、ストラングラーパターンがあります Spring Cloud を用いた実現例を交えながら、ストラングラーパターンについて紹介します
  • 3. © 2020 NTT DATA Corporation 3 自己紹介 名前: 横井一輝 所属: NTTデータ 技術革新統括本部 業務: アプリケーションのモダナイゼーション支援 趣味: ドライブ、サウナ、温泉 自己紹介 • 保守性の高いソフトウェアを構築することに興味・関心 • 現在、Spring Framework を勉強中 興味・関心 発表者近影
  • 4. © 2020 NTT DATA Corporation 4 モノリスからマイクロサービスへの移行 ~説明編~
  • 5. © 2020 NTT DATA Corporation 5 モノリス と マイクロサービス モノリス DB DB API-Gateway DB DB マイクロサー ビス マイクロサー ビス マイクロサー ビス マイクロサー ビス 単一の大きなシステムが 全ての業務を実行 複数の小さなサービスが 連携して業務を実行
  • 6. © 2020 NTT DATA Corporation 6 モノリス と マイクロサービス のメリット・デメリット モノリスとマイクロサービスにはそれぞれメリット・デメリットがあり、トレードオフの関係となる モノリスの特徴 敏捷性 スケーリング 技術仕様・要件充足 パフォーマンス データ 回復性 運用・監視 アプリケーション全体でデプロイ 全体をスケールしなければならない 個別最適不可だが技術スタックがシンプル パフォーマンスが劣化しにくい データの一貫性を保障しやすい システム全体に影響する 管理の手間が少ない 組織面の一致 アーキテクチャと組織の不一致による負荷 再利用 機能を再利用する機会は従来通り 赤文字:メリット マイクロサービスの特徴 サービスごとにデプロイ、迅速な仕様変更 サービスごとにスケーリングが可能 個別最適化可能だが技術スタック複雑化 パフォーマンスが劣化しやすい データの一貫性が保障しにくい サービスが隔壁となり一部の影響に留まる 管理対象が増える アーキテクチャを組織に一致させて高効率 機能を再利用する機会を広げる
  • 7. © 2020 NTT DATA Corporation 7 モノリス から マイクロサービス への移行 モノリス DB DB API-Gateway DB DB マイクロサー ビス マイクロサー ビス マイクロサー ビス マイクロサー ビス マイクロサービスに移行する際はデメリットが顕在化しやすいため、対応が必要 技術仕様の 複雑化 性能問題 データ 整合性 運用 複雑化
  • 8. © 2020 NTT DATA Corporation 8 モノリスからマイクロサービスへの移行の際に考えること なぜ移行するのか 移行目的の明確化 代替手段の検討 成功基準の明確化 どこで分割するか コードの分割断面 データベースの分割断面 どのサービスから分割する か ビジネス価値軸 分割容易性軸 モノリスと マイクロサービスの統合 データ連携 データ整合性 【今回の発表内容】 移行方針 一度に分割か?段階的に分割か? リスクを抑えた移行方針とは?
  • 9. © 2020 NTT DATA Corporation 9 マイクロサービス移行方針
  • 10. © 2020 NTT DATA Corporation 10 一度に分割するか、段階的に分割するか 一度に分割する ビッグバンリライト 段階的に分割する ストラングラーパターン VS
  • 11. © 2020 NTT DATA Corporation 11 ビッグバンリライト モノリスを捨て去り、マイクロサービスへ一度に分割する方法 モダナイゼーション全般において、ビッグバンリライトはリスキーで失敗に終わる可能性が高い DB API-Gateway DB DB メッ セージ ユー ザー UI 3つの機能を サービスとして分割 DB 単一の大きなシステム 3つの機能が存在 ユーザー メッセージ UI
  • 12. © 2020 NTT DATA Corporation 12 ストラングラーパターン 徐々にモノリスを小さくし、マイクロサービスへ段階的に分割していく方法 クライアントからのアクセスをストラングラーファサードがインターセプトし、モノリスまたは新サービスにルーティング クライアントのアクセス先はストラングラーファサードから変わらないので、マイクロサービス移行を意識しなくてよい 新 サ ー ビ ス 新 サ ー ビ ス 新 サ ー ビ ス 新 サ ー ビ ス ストラングラーファサー ド モノリス 新 サ ー ビ ス 新 サ ー ビ ス ストラングラーファサー ド モノリス 新 サ ー ビ ス ストラングラーファサー ド 早期切り出し あとで切り出し 切り出し完了 アクセスを インターセプト アクセス先は 変わらない アクセスを 振り分ける
  • 13. © 2020 NTT DATA Corporation 13 【参考】チャットアプリでのストラングラーパターン利用例 ストラングラーファサードとしてAPI Gateway を利用し、メッセージ機能から段階的にサービスとして分割していく API-Gateway DB メッ セージ メッセージ機能以外を モノリスに残して サービスとしてコピー DB ユー ザー UI Step2 Step3 DB API-Gateway DB DB メッ セージ ユー ザー UI 3つの機能を サービスとして分割 DB 単一の大きなシステム 3つの機能が存在 ユーザー メッ セージ UI Step1 API-Gateway
  • 14. © 2020 NTT DATA Corporation 14 ビッグバンリライト vs ストラングラーパターン ビッグバンリライト ストラングラーパターン メリット • 移行全体の実装コストは少ない • 失敗のリスクを抑えられる • 移行完了まで待たずに段階的に移行の効果 を得られる • 移行と共に組織を成熟させられる デメリット • 失敗のリスクが高い • リライトが完了するまで、効果が得られない • ストラングラーファサードの実装コストがかかる ユースケース • 小規模なシステム • 移行失敗のリスクが少ない • 移行完了までの期間が短い • 開発組織がマイクロサービスに成熟 • 大規模なシステム • 移行失敗のリスクを抑えたい • 移行完了までの期間が長い • 開発組織がマイクロサービスに未成熟
  • 15. © 2020 NTT DATA Corporation 15 ストラングラーパターンを利用して、段階的に移行する3つの方法 新機能をサービスとして実装 プレゼンテーション層とバックエンドの分離 モノリスを分解してマイクロサービスに抽出
  • 16. © 2020 NTT DATA Corporation 16 方法① 新機能をサービスとして実装 メリット:新規サービスを迅速に実装できる デメリット:既存システムを変更することが難しい DB API-Gateway 単一の大きなシステム 3つの機能が存在 新規サービスを実装 ユーザー メッセージ UI DB ユーザー メッセージ UI DB 新規 サー ビス
  • 17. © 2020 NTT DATA Corporation 17 方法② プレゼンテーション層とバックエンドの分離 メリット:プレゼンテーション層とバックエンドが独立して開発ができる デメリット:バックエンドに、大きなモノリスが残り続ける DB 単一の大きなシステム 3つの機能が存在 ユーザー メッセージ UI DB UI機能を、ユーザー・ メッセージ機能から分 離 ユーザー メッセージ UI
  • 18. © 2020 NTT DATA Corporation 18 方法③ モノリスを分解してマイクロサービスに抽出 メリット:既存システムのアーキテクチャを大幅に改善し、マイクロサービスのメリットをより多く享受できる デメリット:他のパターンと比較して難易度が高い API-Gateway DB メッ セージ モノリスの メッセージ機能を抽出 DB ユー ザー UI DB 単一の大きなシステム 3つの機能が存在 ユーザー メッセージ UI メッ セージ
  • 19. © 2020 NTT DATA Corporation 19 ストラングラーパターンを利用して、段階的に移行する方法の比較 新機能のサービス実装 プレゼンテーション層と バックエンドの分離 モノリスを分解して マイクロサービスに抽出 メリット • 新規サービスを 迅速に実装できる • プレゼンテーション層とバックエン ドが独立して開発ができる • アーキテクチャを大幅に改善し、 マイクロサービスのメリットを より多く享受できる デメリット • 既存システムを変更することが 難しい • バックエンドに、大きなモノリスが 残り続ける • 他のパターンより難易度が高い ユースケース • モノリスの分解は行わない • マイクロサービスの早い段階で の実証 • UI/UXの独立した開発・テスト • 将来プレゼンテーション層から マイクロサービスAPIを呼び出し • モノリスのアーキテクチャを改善 • モノリスに実装されている機能 をマイクロサービスとして抽出
  • 20. © 2020 NTT DATA Corporation 20 モノリスからマイクロサービスへの移行 ~実装編~
  • 21. © 2020 NTT DATA Corporation 21 マイクロサービス移行 シナリオ とある会社で、モノリシックなチャットアプリをモダナイズするというシナリオの中で、 マイクロサービス移行に関連する設計手法や技術を説明していきます。 あと、マイクロサービス 流行ってるらしいから 検討してみて(^^) ユーザー数増えてきたから メッセージ送受信の キャパを向上させて欲しい マイクロサービス? ナニそれ? オイシイの?
  • 22. © 2020 NTT DATA Corporation 22 チャットアプリの現行アーキテクチャ 開発言語:Java フレームワーク:Spring Boot データベース:HSQL 実装機能: 1. UI 2. ユーザー管理機能 3. メッセージ管理機能 DB ユーザー メッセージ UI Spring Boot メッセージ管理機能の スケーラビリティ向上が マイクロサービス移行の目的 こちらのチャットアプリをサンプルアプリとして、マイクロサービス移行の検証を行なっていきます
  • 23. © 2020 NTT DATA Corporation 23 新機能のサービス実装 プレゼンテーション層と バックエンドの分離 モノリスを分解して マイクロサービスに抽出 メリット • 新規サービスを 迅速に実装できる • プレゼンテーション層とバックエン ドが独立して開発ができる • アーキテクチャを大幅に改善し、 マイクロサービスのメリットを より多く享受できる デメリット • 既存システムを変更することが 難しい • バックエンドに、大きなモノリスが 残り続ける • 他のパターンより難易度が高い ユースケース • モノリスの分解は行わない • マイクロサービスの早い段階で の実証 • UI/UXの独立した開発・テスト • 将来プレゼンテーション層から マイクロサービスAPIを呼び出し • モノリスのアーキテクチャを改善 • モノリスに実装されている機能 をマイクロサービスとして抽出 今回採用したストラングラーパターン メッセージ管理機能 を改善したいので選択
  • 24. © 2020 NTT DATA Corporation 24 マイクロサービス 移行手順 最初に、ストラングラーパターンでマイクロサービスの切り出しを行う その後、ロードバランサーやサーキットブレーカーを実装し、よりクラウドネイティブにシフトしていく DB ユー ザー メッ セージ UI API-Gateway DB メッ セージ DB ユー ザー UI API-Gateway DB メッ セージ DB ユー ザー UI メッ セージ API-Gateway DB メッ セージ DB ユー ザー UI メッ セージ ストラングラーパターン によるサービス切り出し ロードバランサによる 負荷分散 サーキットブレーカによる 障害対応 メッ セージ メッ セージ
  • 25. © 2020 NTT DATA Corporation 25 ストラングラーパターンによるサービス切り出し
  • 26. © 2020 NTT DATA Corporation 26 ストラングラーパターンによるサービス切り出し DB API-Gateway DB メッ セージ ユーザー メッ セージ UI DB ユー ザー UI ストラングラーパターンを使って、メッセージサービスを安全に切り出し Spring Cloud Gatewayを利用してAPI ゲートウェイを実装 ストラングラーパターン でメッセージサービス に切り出し メッセージ機能を 安全に切り出して スケーラビリティ 向上させたい
  • 27. © 2020 NTT DATA Corporation 27 Spring Cloud Gateway とは • 様々な要素でルーティングルールを設定 • URLパス • ヘッダーやクッキーの値 • メソッド(GET、POSTなど) • 時間(〇時以前、以降など) • リクエスト、レスポンスの内容をフィルターで書き換え • サーキットブレーカー、サービスディスカバリ、セキュリティの機能との統合も可能 • 類似のライブラリ Spring Cloud Netflix Zuul はメンテナンスモードに移行 現在は Spring Cloud Gateway の使用が推奨されてる API ゲートウェイ を構築するための、シンプルかつ柔軟な ライブラリ 今回の検証バージョン Spring Boot 2.3.5, Spring Cloud Hoxton.SR8
  • 28. © 2020 NTT DATA Corporation 28 Step 1. ストラングラーファサードの実装 1. ストラングラーファサードの実装 2. モノリスからマイクロサービスへの 抽出(AP) 3. モノリスからマイクロサービスへの 抽出(DB) 4. ストラングラーファサードの呼び出し 先の書き換え 5. 認証情報の連携 API-Gateway DB ユーザー メッセージ UI localhost:8080 localhost:8081 Spring Cloud Gateway Spring Boot
  • 29. © 2020 NTT DATA Corporation 29 ストラングラーファサードの実装 1. Spring Initializr から Spring Cloud Gateway を依存関係に追加したアプリケーションを作成 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> Mavenを利用する場合 pom.xml に追記 Gateway を追加
  • 30. © 2020 NTT DATA Corporation 30 ストラングラーファサードの実装 2. RouteLocator の Bean を作成し、ルーティングルールを設定 @SpringBootApplication public class Application { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p.path("/**") .uri("http://localhost:8081") ) .build(); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } パスのパターンマッチにアスタリスクで全マッチ 全リクエストをモノリス(localhost:8081)に転送 Java config の場合 (yaml で記述することも可能)
  • 31. © 2020 NTT DATA Corporation 31 Step 1. ストラングラーファサードの実装 の課題 ■課題 Logout実行時、リダイレクト先を示す Locationヘッダーが :8081/login で帰ってくるため 正しくページ遷移しない ■アプローチ API Gatewayにて、 Location ヘッダーの値を書き換える 必要がある API-Gateway DB ユーザー メッセージ UI localhost:8080 localhost:8081 :8081/Logout :8080/Logout Location :8081/Login Location :8081/Login × Location :8080/Login ○
  • 32. © 2020 NTT DATA Corporation 32 レスポンスの Location ヘッダーの値を書き換え(実装) return builder.routes() .route(p - > p .path("/**") .filters(f - > f .rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "localhost:8080", "http")) .uri("http://localhost:8081") ) .build(); レスポンスヘッダーに Location が存在する場合は フィルターでホスト名を localhost:8080 に書き換え
  • 33. © 2020 NTT DATA Corporation 33 Step 2. モノリスからマイクロサービスへの抽出(AP) 1. ストラングラーファサードの実装 2. モノリスからマイクロサービスへの 抽出(AP) 3. モノリスからマイクロサービスへの 抽出(DB) 4. ストラングラーファサードの呼び出し 先の書き換え 5. 認証情報の連携 localhost:8080 localhost:8081 API-Gateway メッ セージ DB ユー ザー UI メッ セージ localhost:8082 Spring Boot
  • 34. © 2020 NTT DATA Corporation 34 Step 2. モノリスからマイクロサービスへの抽出(AP)の課題 ■課題 共通ライブラリの存在や 他機能と密結合しているなどで、 メッセージサービスだけをきれいに 抽出することが困難 ■解決策 メッセージサービスだけを 抽出しようとせずに、 大きめにサービスを抽出してから、 不要なコードを削ぎ落としていく localhost:8080 localhost:8081 DB ユー ザー UI メッ セージ localhost:8082 Spring Boot ユー ザー UI ユー ザー UI メッ セージ API-Gateway
  • 35. © 2020 NTT DATA Corporation 35 Step 3. モノリスからマイクロサービスへの抽出(DB) 1. ストラングラーファサードの実装 2. モノリスからマイクロサービスへの 抽出(AP) 3. モノリスからマイクロサービスへの 抽出(DB) 4. ストラングラーファサードの呼び出し 先の書き換え 5. 認証情報の連携 localhost:8080 localhost:8081 API-Gateway メッ セージ DB ユー ザー UI メッ セージ Spring Boot localhost:8082 ユー ザー メッ セージ メッ セージ メッ セージ
  • 36. © 2020 NTT DATA Corporation 36 Step 3. モノリスからマイクロサービスへの抽出(DB) の課題 ■課題 以下の場合、モノリスとマイクロサービス のデータ連携を設計する必要がある • 切り出すAPとモノリスに残るAPが 同一のテーブルにアクセス • 切り出すテーブルとモノリスに残る テーブルが、外部結合している (今回のパターン) ■解決策の選択肢 • モノリスAPを通して モノリスDBのデータを参照 • モノリスDBに マイクロサービスAPが直接参照 • モノリスDB更新をトリガーに マイクロサービスDBに更新を反映 DB ユー ザー UI メッ セージ API-Gateway DB メッ セージ Spring Boot ユーザー情報 更新リクエスト ユーザー テーブル更新 ユー ザー メッ セージ 最新のユーザー情報 はどこ?
  • 37. © 2020 NTT DATA Corporation 37 モノリスからマイクロサービスへのデータ連携の解決策 API-Gateway メッ セージ ユー ザー UI API-Gateway メッ セージ ユー ザー UI API-Gateway メッ セージ ユー ザー UI ユー ザー ユー ザー ユー ザー メッ セージ メッ セージ メッ セージ ユー ザー モノリスAPを通して モノリスDBのデータを参照 モノリスDBに マイクロサービスAPが直接参照 モノリスDB更新をトリガーに マイクロサービスDBに更新を反映 メリット: サービスの疎結合が保たれる デメリット: モノリスAPの修正が必要 メリット: 実装コストが低い デメリット: モノリスDBと密結合になる メリット: サービスの疎結合が保たれる デメリット: 更新反映用の部品が必要 参照 更新
  • 38. © 2020 NTT DATA Corporation 38 Step 4. ストラングラーファサードの呼び出し先の書き換え 1. ストラングラーファサードの実装 2. モノリスからマイクロサービスへの 抽出(AP) 3. モノリスからマイクロサービスへの 抽出(DB) 4. ストラングラーファサードの呼び出 し先の書き換え 5. 認証情報の連携 localhost:8080 localhost:8081 API-Gateway DB ユー ザー UI メッ セージ localhost:8082 UI・ユーザー機能 メッセージサービス DB メッ セージ
  • 39. © 2020 NTT DATA Corporation 39 Step 4. ストラングラーファサードの呼び出し先の書き換え の課題 ■課題の背景 STOMP というメッセージングプロトコル (WebSocket通信の一種) を利用して、チャットの送受信を実装 ■課題 WebSocket通信とHTTP通信の 通信プロトコルの違いによる ルーティング設定ができない ■解決法 STOMPプロトコルに沿った URLパスベースのルーティングを 設定する必要がある STOMPのメッセージフロー
  • 40. © 2020 NTT DATA Corporation 40 STOMP プロトコルに沿った 切り出し先サービスへのルーティング設定(実装) return builder.routes() .route(p - > p .path("/chat/messages").or().path("/messages/**") .uri("http://localhost:8082")) .route(p - > p .path("/topic/**").or().path("/chat/messages/{segment}/**") .uri("ws://localhost:8082")) .route(p - > p .path("/**") .filters(f - > f .rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "localhost:8080", "http")) .uri("http://localhost:8081")) .build(); WebSocket 通信用の ルーティング設定 http通信用の ルーティング設定
  • 41. © 2020 NTT DATA Corporation 41 Step.5 認証情報の連携 1. ストラングラーファサードの実装 2. モノリスからマイクロサービスへの 抽出(AP) 3. モノリスからマイクロサービスへの 抽出(DB) 4. ストラングラーファサードの呼び出し 先の書き換え 5. 認証情報の連携 API-Gateway DB ユー ザー UI メッ セージ DB メッ セージ 太郎さんが ログイン 太郎さんが メッセージ送信 太郎さんを 認証 メッセージ送信 したのは誰?
  • 42. © 2020 NTT DATA Corporation 42 Step.5 認証情報の連携の課題 ■課題 モノリシックなシステムでは セッション認証を採用していた。 しかし、切り出し先のマイクロサービスは モノリシックが認証した情報を 知ることができない。 ■解決策の選択肢 • 単純なBasic 認証 • JWTを使ったトークン認証 ← 採用 • OAuth 2.0 認証・認可 API-Gateway DB ユー ザー UI メッ セージ DB メッ セージ セッション認証 認証情報をどう 連携するのか?
  • 43. © 2020 NTT DATA Corporation 43 JWTを 返却 Step.5 認証情報の連携(アクセストークン認証) 1. ユーザーIDとパスワードを入力して ログインリクエストを送る 2. モノリスにログインリクエストを ルーティングする 3. モノリスが JWT トークンを クッキーに入れて返却 4. メッセージサービスを呼び出すとき JWT トークンをクッキーに含む リクエストを送る 5. APIゲートウェイが JWT トークンを Authorizationヘッダーに 組み込む 6. メッセージサービスが JWT トークンを検証 API-Gateway DB ユー ザー UI メッ セージ DB メッ セージ ① ② ④ ⑤ ⑥ IDとPWで ログイン IDとPWで ログイン JWTをクッキー に与える JWTを認可ヘッダー に与える JWTを 検証 ③
  • 44. © 2020 NTT DATA Corporation 44 認証情報の連携(実装) return builder.routes() .route(p - > p .path("/chat/messages").or().path("/messages/**") .filters(f - > f .filter(preGatewayFilterFactory.apply(new Config())) .uri("http://localhost:8082")) .route(p - > p .path("/topic/**").or().path("/chat/messages/{segment}/**") .filters(f - > f .filter(filter(preGatewayFilterFactory.apply(new Config())) .uri("ws://localhost:8082")) .route(p - > p .path("/**") .filters(f - > f .rewriteLocationResponseHeader("AS_IN_REQUEST", "Location", "localhost:8080", "http")) .uri("http://localhost:8081")) .build(); ゲートウェイ フィルタ を自作し リクエストやレスポンスの中身を 自由自在に書き換え可能
  • 45. © 2020 NTT DATA Corporation 45 認証情報の連携(実装) public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> { (中略) @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { Optional<HttpCookie> token = Optional.ofNullable(exchange.getRequest().getCookies().getFirst("USERINFO")); if (token.isEmpty()) return chain.filter(exchange); ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); builder.headers((httpHeaders) -> { httpHeaders.set("Authorization", token.get().getValue()); }); return chain.filter(exchange.mutate().request(builder.build()).build()); }; } (中略) } Authorization ヘッダーに アクセストークンを付与 Cookie 情報から アクセストークンを取得 自作した ゲートウェイ フィルタ
  • 46. © 2020 NTT DATA Corporation 46 マイクロサービス移行 シナリオ ~途中経過~ マイクロサービス移行の第一段階を終え、メッセージ管理機能の切り離しに成功。 当初の「メッセージ管理機能の性能向上」の目的を果たすため、引き続きマイクロサービス移行を実施する。 ところで、 メッセージ機能の性能は 向上したのかね?? マイクロサービス移行。 ご苦労だった。 できたー! マイクロサービス 完全に理解!! 性能向上の目的 を忘れてた……
  • 47. © 2020 NTT DATA Corporation 47 ロードバランサーによる負荷分散
  • 48. © 2020 NTT DATA Corporation 48 ロードバランサーによる負荷分散 API-Gateway DB メッ セージ DB ユー ザー UI API-Gateway DB メッ セージ DB ユー ザー UI メッ セージ メッ セージ ロードバランサーを使って、アクセスの負荷を分散 Spring Cloud LoadBalancer と Spring Cloud Netflix Eureka を利用 メッセージサービスを 多重化して ロードバランサーで 負荷分散 アクセス集中時の メッセージサービスへの 負荷を分散したい
  • 49. © 2020 NTT DATA Corporation 49 Spring Cloud LoadBalancer と Spring Cloud Netflix Eureka とは Spring Cloud LoadBalancer • ロードバランサーを構築するためのライブラリ • メンテナンスモードに移行した Netflix Ribbon の代わりに使用が推奨 • Ribbon で行っていた作業を抽象化して提供されている Spring Cloud Netflix Eureka • Netflix 社製のサービスディスカバリ用のサービスレジストリとクライアントを構築するライブラリ • サービスディスカバリを利用することで、DNSのようにサービス名からIPアドレス取得することが可能 • Eureka はメンテナンスモードへの移行はいまのところ宣言されていない ロードバランサーとサービスディスカバリを Spring で構築するためのライブラリ 今回の検証バージョン Spring Boot 2.3.5, Spring Cloud Hoxton.SR8
  • 50. © 2020 NTT DATA Corporation 50 Step 1. Eureka サービスレジストリ の作成・起動 1. Eureka サービスレジストリを 作成・起動 2. クライアントを サービスレジストリに登録 3. サービス一覧を取得し、 リクエストをロードバランサーで分散 API-Gateway DB ユー ザー UI メッ セージ DB メッ セージ サービス レジストリ メッ セージ サービス名 アドレス ①起動
  • 51. © 2020 NTT DATA Corporation 51 Eureka サービスレジストリ の作成・起動(実装) 1. Spring Initializr から Eureka Server を依存関係に追加した アプリケーションを作成 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> Mavenを利用する場合 Eureka サービスレジストリの 依存関係をpom.xml に追記 Eureka Server を追加
  • 52. © 2020 NTT DATA Corporation 52 Eureka サービスレジストリ の作成・起動(実装) 2. テスト用の設定を application.properties に追記 3. サービスレジストリを有効にするためアノテーション “@EnableEurekaServer” を追加 @EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } } Eureka サービスレジストリの アプリケーションクラスに @EnableEurekaServer を追加 server.port=8761 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false logging.level.com.netflix.eureka=OFF logging.level.com.netflix.discovery=OFF テスト用の単純目的のため 自分自身の登録を無効化
  • 53. © 2020 NTT DATA Corporation 53 Step 2. サービスレジストリに登録 1. Eureka サービスレジストリを 作成・起動 2. クライアントを サービスレジストリに登録 3. サービス一覧を取得し、 リクエストをロードバランサーで分散 API-Gateway DB ユー ザー UI メッ セージ DB メッ セージ サービス レジストリ メッ セージ ②登録 ①起動 サービス名 アドレス サービス名 アドレス message localhost:8082 localhost:8083
  • 54. © 2020 NTT DATA Corporation 54 サービスレジストリに登録(実装) 1. メッセージサービスに Eureka Discovery Client の依存関係を追加 2. サービスレジストリに登録するためのアノテーション “@EnableDiscoveryClient” を追加 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> @EnableDiscoveryClient @SpringBootApplication public class MessageApplication { public static void main(String[] args) { SpringApplication.run(MessageApplication.class, args); } } メッセージサービスの pom.xml に依存関係を追記 メッセージサービスの アプリケーションクラスに @EnableDiscoveryClient を追加
  • 55. © 2020 NTT DATA Corporation 55 サービスレジストリに登録(実装) 3. サービスレジストリに登録するサービス名を application.properties に設定 4. 同じサービス名で複数起動することで、多重度が上がる server.port=8082 spring.application.name=message サービス名を設定 server.port=8082 spring.application.name=message server.port=8083 spring.application.name=message メッセージサービス① 用のプロパティ メッセージサービス② 用のプロパティ
  • 56. © 2020 NTT DATA Corporation 56 Step 3.サービス一覧を取得し、リクエストをロードバランサで分散 1. Eureka サービスレジストリを 作成・起動 2. クライアントを サービスレジストリに登録 3. サービス一覧を取得し、 リクエストをロードバランサで分散 API-Gateway DB ユー ザー UI メッ セージ DB メッ セージ サービス レジストリ メッ セージ ②登録 ①起動 ③リクエスト分散 ③サービス一覧を取得 サービス名 アドレス message localhost:8082 localhost:8083
  • 57. © 2020 NTT DATA Corporation 57 サービス一覧を取得し、リクエストをロードバランサで分散(実装) 1. Spring Cloud Gateway に Eureka Discovery Client の依存関係を追加 2. Spring Cloud Gateway の application.properties に設定 spring.cloud.gateway.discovery.locator.enabled=true spring.cloud.loadbalancer.ribbon.enabled=false <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> Spring Cloud Gatewayの pom.xml に 依存関係を追記 サービスディスカバリを有効化して サービス一覧を取得する設定 Netflix Ribbon を無効化し Spring Cloud LoadBalancer を 有効化するための設定
  • 58. © 2020 NTT DATA Corporation 58 API ゲートウェイからのアクセスをロードバランサで振り分け(実装) 3. Spring Cloud Gateway の RouteLocator の Bean を修正しロードバランシングできるように設定 return builder.routes() .route(p - > p .path("/chat/messages").or().path("/messages/**") .uri("lb://message")) .route(p - > p .path("/topic/**").or().path("/chat/messages/{segment}/**") .uri("lb:ws://message")) `lb://[サービス名]` と記述することで ロードバランサを利用可能 http://localhost:8082 → lb://message WebSocket通信の際は `lb:ws://[サービス名]` と記述する ws://localhost:8082 → lb:ws://message
  • 59. © 2020 NTT DATA Corporation 59 サーキットブレーカーによる障害対応
  • 60. © 2020 NTT DATA Corporation 60 サーキットブレーカーによる障害対応 API-Gateway DB メッ セージ DB ユー ザー UI メッ セージ メッ セージ API-Gateway DB メッ セージ DB ユー ザー UI メッ セージ メッ セージ サーキットブレーカーを使って、サーバー高負荷時はアクセスを一時遮断 Spring Cloud Circuit Breaker と Resilience4J を利用 サーバーレスポンスが 遅い場合は アクセスを一時遮断 サーバー高負荷時に サーバーレスポンスが 遅い場合も アクセスは止まらない
  • 61. © 2020 NTT DATA Corporation 61 Spring Cloud Circuit breaker とは • メンテナンスモードに移行した Netflix Hystrix の代わりに使用が推奨 • さまざまなサーキットブレーカーの実装にわたって抽象化を提供されており、 開発者はアプリケーションのニーズに最適なサーキットブレーカーを選択可能 • 下記のサーキットブレーカーと組み合わせて使用可能 • Hystrix • Resilience4J • リアクティブ Resilience4J ← 今回使用 • Spring Retry • Sentinal サーキットブレーカーを Spring で構築するためのライブラリ 今回の検証バージョン Spring Boot 2.3.5, Spring Cloud Hoxton.SR8
  • 62. © 2020 NTT DATA Corporation 62 サーキットブレーカによる障害対応(実装) 1. Spring Cloud Gateway に Resilience4j の依存関係を追加 2. Spring Cloud Gate に Resilience4j の設定を修正する Bean を追記 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId> </dependency> Spring Cloud Gatewayの pom.xml に追記 @Bean public Customizer <ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() { return factory - > factory .configureDefault(id - > new Resilience4JConfigBuilder(id) .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) .timeLimiterConfig(TimeLimiterConfig.custom() .timeoutDuration(Duration.ofSeconds(4)).build()) .build()); } 4秒以内にレスポンスがない場合 サーキットブレーカーが発動する設定
  • 63. © 2020 NTT DATA Corporation 63 サーキットブレーカによる障害対応(実装) 3. Spring Cloud Gateway の RouteLocator にサーキットブレーカーフィルターを追加 4. Spring Cloud Gateway に アクセス遮断時の既定レスポンスを実装 .route(p -> p.path(“/chat/messages”).or().path(“/messages/**”) .filters(f -> f .circuitBreaker(c -> c.setFallbackUri("forward:/fallback"))) .uri("lb://message")) @RequestMapping("/fallback") public Mono<String> fallback () { return Mono.just("You can't access message service..."); } アクセス遮断時に呼ばれる URIを設定 アクセス遮断時の 既定レスポンス
  • 64. © 2020 NTT DATA Corporation 64 まとめ
  • 65. © 2020 NTT DATA Corporation 65 マイクロサービス移行 シナリオ ~エピローグ ~ マイクロサービス移行を終え、メッセージ管理機能の切り離しと、負荷分散・障害対応を実施。 マイクロサービス・リーダーに任命され、引き続きマイクロサービス移行を担当していくことに。 君を マイクロサービス・リーダー に任命する。 今度こそ マイクロサービス移行。 ご苦労だった。 やったー! マイクロサービス リーダーだ!!
  • 66. © 2020 NTT DATA Corporation 66 まとめ モノリスを分割することで、ミドルウェアが隠ぺいしていたことの再設計が必要になる 段階的に移行する方針は、設計漏れを早期に発見できる点で、リスクを下げて移行できる 今後は分割断面の見つけ方や、モノリスとマイクロサービス間のデータ連携について検証していきたい また、今回は Spring Cloud を用いてロードバランサやサーキットブレーカを実装した しかしこれらは、Istio などのサービスメッシュや AWS などのクラウドサービスでも同様のことができる 今後、これらとの比較検証も行っていきたい 気づき • リスクをさげてマイクロサービスに移行する戦略として、ストラングラーパターンの紹介 • マイクロサービスに移行するためのデモンストレーション • ストラングラーパターンの実装 • ロードバランサの実装 • サーキットブレーカを実装 まとめ
  • 67. © 2020 NTT DATA Corporation 67 参考情報 Spring I/O 2018 報告会 - Spring Cloud Gateway / Spring Cloud Pipelines https://www.slideshare.net/JunyaKatada/spring-io-2018-spring-cloud-gateway-spring- cloud-pipelines ぱぱっと理解するSpring Cloudの基本 https://www.slideshare.net/kazukikumagai1/spring-cloud Introducing Spring Cloud Gateway by Spencer Gibb @ Spring I/O 2018 https://www.youtube.com/watch?v=NkgooKSeF8w Monolith to Microservice デモアプリ https://github.com/spencergibb/monolith-to-microservices
  • 68. © 2020 NTT DATA Corporation 本資料に記載されている会社名、商品名、又はサービス名は、各社の登録商標又は商標です。