SlideShare a Scribd company logo
マイクロサービス
4つの分割アプローチ
2019年5月18日
ギルドワークス 増田 亨
本日の内容について
2019/5/18 2
実証されたパターンの紹介ではない
2019/5/18 3
私の模索の現時点のスナップショット
2019/5/18 4
参考になれば幸いです
2019/5/18 5
マイクロサービスを実現する技術
クラウド
コンテナ
設計スキル
2019/5/18 6
マイクロサービスを実現する技術
クラウド
コンテナ
設計スキル
2019/5/18 7
マイクロサービス:4つの動機
負荷分散
リスク分散
データ分散
機能分散
ロードバランサ/ルータ
+
同一サービスの複製群
コーディネータ
+
異なるサービス群の連携
排他の選択肢ではなく、組み合わせになる
2019/5/18 8
マイクロサービス:4つの動機
負荷分散
リスク分散
データ分散
機能分散
異なるサービス群に
分解して連携する
2019/5/18 9
基本のアプローチ
モノリスで作って
モジュール設計を
改善する
マイクロサービスの
可能性を検討する
マイクロサービスへ
移行を検討する
部分適用 部分適用
2019/5/18 10
設計スキルの基本は同じ
関心の分離
高凝集・疎結合
モジュール化
(インタフェース定義+実装)
2019/5/18 11
サービスの模式図
ビジネス
ロジック
同期
非同期
リクエスト/
レスポンス
非同期
receive
subscribe
同期
非同期
非同期
リクエスト/
レスポンス
send
publish
データソース
ローカルな
データベース
他の
サービス
リクエスト/
レスポンス
モノリス/ひとつのマイクロサービスに共通の構造
個々の実体は、このサブセット
2019/5/18 12
イ
ン
バ
ウ
ン
ド
ア
ウ
ト
バ
ウ
ン
ド
マイクロサービスへの分割
2019/5/18 13
どこまで小さくできるか?
2019/5/18 14
「理論」的には Java APIのメソッド単位
限界はクラウド/コンテナ/設計/運用の習熟度
どこまで小さくできるか?
2019/5/18 15
どこまで小さくするか?
2019/5/18 16
どこまで小さくするか?
論理的なモジュール分割
物理的な配置と運用単位
積極的に!
大胆に!
慎重に!
一歩ずつ!
2019/5/18 17
マイクロサービス間の通信
8つの勘違いと真実
2019/5/18 18
ネットワークは信頼できる → 必ず落ちる
ネットワークは遅延しない → メモリに比べとんでもなく遅い
ネットワークの帯域は無限である → 帯域は有限
ネットワークは安全である → アクセスできている=穴が開いている
ネットワーク構成は変化しない → 誰かが前触れもなく変更する
一人の管理者が集中管理してくれる → 複数人がばらばらに管理している
転送コストはゼロである → データ転送はお金がかかる
ネットワーク全体は等質である → 性質の異なる構成要素のごった煮
出典:Fallacies of Distributed Computing Explained
http://www.rgoarchitects.com/Files/fallacies.pdf
勘違い 真実
2019/5/18 19
マイクロサービス
4つの分割アプローチ
2019/5/18 20
ビジネスファンクション
(業務機能)
動詞/ユースケース
名詞/リソース
境界づけられたコンテキスト/ サブドメイン
(ドメイン駆動設計由来の分割)
2019/5/18 21
実際にはこれらの組み合わせになる
ビジネスファンクション
(業務の活動単位)
2019/5/18 22
受注
在庫確認
出荷事務
売上事務
出荷作業
請求
回収
購買計画
発注
購買
納品管理
支払い
現品管理
実地棚卸
在庫評価
会計連動
手形
外貨
業績管理販売分析 購買分析
21の業務機能に分割した例
2019/5/18 23
ビジネスファンクションによる分割
✓業務の活動単位・管理単位を、そのままシステム構造に反映
✓サービス間連携が(現実世界と同じ)複雑さになりやすい
✓大企業の場合
➢ 業務機能ごとに部門が分かれている
➢ 商品カテゴリ、担当地域などでさらに細分化が必要かも
➢ 大企業病(非効率、硬直化、調整ごとの多さ、合意形成までの時間)がシステ
ムの開発・運用に、そのまま持ち込まれる
✓中小企業の場合
➢ 複数の業務機能をひとつの部門が担当する
➢ 業務機能をまたがった要求がでてきやすい(システム構造との不整合がおき
やすい)
2019/5/18 24
業務機能での分割
2019/5/18 25
共有データベース
受
注
出
荷
事
務
売
上
事
務
出
荷
作
業
請
求
回
収
モノリス
受注
在庫確認
出荷事務
売上事務
出荷作業
請求
回収
分割イメージ
課題:データの一貫性、修正や取消の流れ
動詞/ユースケース
2019/5/18 26
受注データを入力する
出荷を依頼する
売上を計上する
請求を依頼する
営業担当者
〇〇が□□を△△する
2019/5/18 27
動詞/ユースケースで分割
✓機能要求として分割しやすい
✓開発範囲の定義がやりやすい
✓トランザクション単位のマイクロサービスになる
➢サービス間で、ロジックの重複、断片化が起きやすい
➢サービスの肥大化 and/or 類似サービスの乱立
➢バッチ処理が増えやすい
ロジックの重複や断片化の後始末
2019/5/18 28
薄いユースケースサービス
2019/5/18 29
受注データを
入力する
価格設定
サービス
在庫確認
サービス
与信管理
サービス
受注データ
記録サービス
ここに複雑なロジックを
書かない
ロジックを、領域ごとに
分割して整理・記述して、
ロジックの重複や断片化を
なくす
名詞/リソース
2019/5/18 30
商品
顧客
取引先
在庫
受注
拠点
部門
発注
リソース指向
識別番号単位で状態の更新と参照を行う
社員
2019/5/18 31
名詞/リソースで分割
✓エンティティ+CRUD
✓データ更新に責任を持つサービスを明確できる
✓リソース単位をまたがった参照が複雑になりがち
➢ 外部キー参照制約、JOINが使えない世界
注文データが顧客番号と商品番号を持つ
✓異なる関心事が混在し、肥大化しがち
➢ 顧客
識別情報、プロファイル、連絡先、購入履歴、プリファレンス、コミュニ
ケーション履歴、認証・認可の設定、アクセス履歴、 …
➢ 商品
識別情報、説明、仕様、価格、在庫状態、物流特性、…
2019/5/18 32
リソース管理単位の分割
2019/5/18 33
顧客系リソース 商品系リソース
ID-氏名
プロファイル
連絡先
購入履歴
プリファレンス
コミュニケー
ション履歴
認証認可
設定
アクセス
履歴
番号-名前
商品カタログ
仕様詳細
価格
物流特性
仕入特性
取り扱い状態 在庫状態
モノリスのリソース管理を、こういう単位のCRUDに分割しながら
マイクロサービスへの移行を検討する
境界づけられたコンテキスト/サブドメイン
(ドメイン駆動設計由来の分割)
2019/5/18 34
わからん!
2019/5/18 35
解釈も定義も説明もばらばら…
原因の一つはバーノンの「実践ドメイン駆動設計」の説明が、
エヴァンスの「ドメイン駆動設計」とは、だいぶ違った独自の解釈と説明だから
ドメイン
2019/5/18 36
モデル
サブ
ドメイン サブ
ドメイン
サブ
ドメイン
境界づけられた
コンテキスト
サブドメイン
サブドメイン
コンテキスト
コンテキスト
コンテキスト
エヴァンス流
コンテキスト → モデル → サブドメイン
バーノン流
ドメイン → サブドメイン → コンテキスト
エヴァンス流の定義
✓Bounded Context : 境界づけられたコンテキスト
➢ひとつのモデルを一貫して適用できる範囲
➢境界の実体
⚫ チーム(密接なコミュニケーションの範囲)
⚫ ソースコードやDBスキーマの所有権(変更可能範囲)
✓サブドメイン
➢特定のモデルの中の、独立性の高い、凝集した塊
2019/5/18 37
どちらもマイクロサービスの単位になりえる
実際には、サブドメインは設計の見直しで定義しなおすことが多い
サブドメインでマイクロサービスに分けるのは設計改善の障害になりやすい
境界づけられたコンテキスト
✓ひとつのコンテキストに一つのモデルを目指す(目標)
✓現実
➢一つのコンテキストに、複数のモデルが発生する
➢一つであるべきモデルが、複数のコンテキストに断片化する
✓やるべきこと
➢一つのコンテキスト(開発単位)に一つのモデルを維持すること
➢モデルが異なれば、別のコンテキスト(開発単位)に分割すること
2019/5/18 38
ドメイン駆動設計の「モデル」
2019/5/18 39
ドメイン駆動設計の「モデル」
✓ソフトウェアの核心にある複雑さに立ち向かう
✓核心にある複雑さ=ビジネスルールの複雑さ
✓ビジネスルールの複雑さをシンプルに説明できる「モデル」を探
す
✓ビジネスルールのモデル(説明)を、そのままコードで表現するこ
とで、ソフトウェアがわかりやすく変更が楽で安全になる
✓ビジネスルールの整理の構造がソフトウェア構造になる
2019/5/18 40
ビジネスルールの分割パターン
2019/5/18 41
価格ポリシー
割引ルール
取引ポリシー
サービス提供
ポリシー
特典ルール
いつ
どこで
どのレベルで
与信管理
取引先審査
外貨換算
キャンセル
ポリシー
購買ポリシー
ビジネスルール中心の構造
2019/5/18 42
ビジネスルールに基づく
計算サービス
判断サービス
リソース管理
サービス
問い合わせ
サービス
登録
サービス
モノリスをこういう構造に分解しながら
マイクロサービスへの移行を検討する
4つの分割アプローチのまとめ
2019/5/18 43
2019/5/18 44
ビジネスファンクション 業務の活動単位・管理単位で分割する
動詞/ユースケース 機能要求一覧で分割する
名詞/リソース エンティティ+CRUD
ビジネスルール中心
境界づけられたコンテキスト
サブドメイン
(ドメイン駆動設計由来の分割)
トランザクションの分解
2019/5/18 45
モノリスのトランザクション単位はもっと分解できる
あるいは、もっと分解すべき
(時間があれば)
トランザクション 分解パターン
2019/5/18 46
パイプライン化 (VETRO)
コーディネータ (Saga)
状態更新の非同期化 (EH-SM-DSQ)
パイプライン化 (VETRO)
2019/5/18 47
パイプライン化 (VETRO)
Validation
妥当性検証
Enrich
情報付加
Translate
情報導出
Routing
分岐判定
Operation
通知/記録
inbound
メッセージ
トランザクションを実行するステップの分解
それぞれのステップで、ビジネスルールを実行する
2019/5/18 48
inbound
メッセージ
Event 通知、Document送付
Query 問い合わせ、Command 指示
Validation
妥当性検証
メッセージ内容の妥当性を検証する
データ形式、必須属性、値範囲、…
Enrich
情報付加
メッセージに含まれたIDなどから、関連する情報を収集
するルール(ex. 顧客ID->顧客購買履歴)
Translate
情報導出
付加された情報を元に、新たな情報を導出するルール
(ex. 購買履歴 → 顧客ランク )
Routing
分岐判定
導出された情報を元に、適切なオペレーションに分岐さ
せるルール ( ex. 顧客ランクごとの対応 )
Operation
通知/記録
通知ルール:誰に何を通知すべきか?
記録ルール:どこに何を記録すべき?
2019/5/18 49
コーディネータ (Saga)
2019/5/18 50
コーディネータ (Saga)
③が不成立だった場合、①と②にキャンセル処理を実行する
さまざまな状況と、その対応方法(undo)の物語を用意する
①②③を、独立して、順不同で実行する
三つともOKであれば完了(Happy Goal)
①独立したトランザクション A
②独立したトランザクション B
③独立したトランザクション C
inbound
メッセージ
コーディ
ネータ
ひとつの大きなトランザクション → 独立した複数の小さなトランザクションに分割
2019/5/18 51
Sagaパターン
✓独立したトランザクション
➢個々のトランザクションを独立して確定する(できる)
✓ビジネス的な undo の仕組み
➢どこかで不都合な状況が発生した場合、キャンセル処理な
ど「カウンタートランザクション」を実行する
✓ビジネスレベルでの代替アクションの分析と実装
➢自動的なundo以外に、人間系の代替プロセスや取消プロセ
スに引き継ぐパターンも選択肢
➢その場合の支援機能を用意する
2019/5/18 52
状態更新の非同期化
(EH-SM-DSQ)
2019/5/18 53
状態更新の非同期化
イベント記録
Event History
イベント履歴に追記のみ
状態は更新しない
状態は、履歴を再生して
動的に導出する
状態の実体化
State Materialize
目的ごとに必要な状態を
導出する
イベント発生とは
非同期に処理
(publish/subscribe)
目的別のクエリ
Domain Specific Query
検索の文脈ごとのクエリ
サービスを提供する
(なんでも検索にしない)
APIがシンプルになる
各クエリのパラメータは数
個にとどめる
2019/5/18 54
Event History - State Materialize – Domain Specific Query
2019/5/18 55
inbound
イベント
イベント
ハンドラ
目的別
状態
状態の
実体化
問合せ
subscribe
目的別
状態
状態の
実体化
問合せ
subscribe
目的別
状態
状態の
実体化
問合せ
subscribe
publish
イベント
履歴
追記
①
②
③
状態は、履歴を再生して導出 問合せを目的別に分解することで、
APIとデータ構造をシンプルにできる
本日のまとめ
2019/5/18 56
基本のアプローチ
モノリスで作って
モジュール設計を
改善する
マイクロサービスの
可能性を検討する
マイクロサービスへ
移行を検討する
部分適用 部分適用
2019/5/18 57
マイクロサービス
4つの分割アプローチ
2019/5/18 58
ビジネスファンクション
(業務機能)
動詞/ユースケース
名詞/リソース
境界づけられたコンテキスト/ サブドメイン
(ドメイン駆動設計由来の分割)
2019/5/18 59
実際にはこれらの組み合わせになる
トランザクションの分解パターン
2019/5/18 60
パイプライン化 (VETRO)
コーディネータ (Saga)
状態更新の非同期化 (EH-SM-DSQ)

More Related Content

マイクロサービス 4つの分割アプローチ