Advertisement

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

ソフトウェアシステムの設計・構築 at システム設計
May. 17, 2019
Advertisement

More Related Content

Slideshows for you(20)

More from 増田 亨(20)

Advertisement

Recently uploaded(20)

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

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