【レポート】AWS Summit Tokyo 2017:〜マイクロサービスを設計する全ての開発者に送る〜クラウド時代のマイクロサービス設計徹底解説! #AWSSummit

aws-summit-tokyo-2017-longlogo 2017年05月30日(火)〜2017年06月02日(金)の計4日間に渡り、グランドプリンスホテル新高輪 品川プリンスホテル アネックスタワーで行われている『AWS Summit Tokyo 2017』。

当エントリでは2017年05月31日に行われた『〜マイクロサービスを設計する全ての開発者に送る〜クラウド時代のマイクロサービス設計徹底解説!』に関する内容をレポートしたいと思います。

セッション概要

当セッションの登壇者及び概要は以下の通り。

スピーカー:
 鈴木 雄介氏 グロースエクスパートナーズ株式会社 アーキテクチャ事業本部 執行役員

セッション概要:
 システムの柔軟性を向上させるにはサービス間連携をベースにしたシステム構成、いわゆるマイクロサービス的な発想が重要です。
では、システムをいかに分割し、いかに連携させていくのがよいのでしょうか?
 本セッションでは、ドメインや業務などのビジネス観点と性能やセキュリティなどの技術的制約を組み合わせて、適切な粒度と結合度を導くための分割と連携の設計指針について考えていきます。
 AWSには多くの選択肢があるのです。

 

セッションレポート

  • 設計入門に変える

なぜマイクロサービスか

  • ウェブサービスの状況
    • システムが巨大化していく
    • それぞれが独自のライフサイクルを持っている
    • でも、ビジネス環境の変化には素早く適応したい

モノリシックにおける戦略

  • アプリ内を分割してコード変更の影響範囲を限定する
  • アプリを1つのノードとして配備し、連携する
  • 問題点
    • 実行時の影響範囲が見えにくい
    • 部分への性能劣化が全体に波及しやすい
    • 巨大化すると難易度があがる

マイクロサービスのアプローチ

  • アプリを機能ごとにサービスで分割していく
    • サービス= 稼動状態にあるアプリケーション。機能だけではなく非機能も切り分けられている
    • サービスは個別ノードに配備し、緩やかに連携している
    • APIを通じて連携しているので、実行時の影響範囲の限定がしやすい
  • 巨大化してもサービス単位で管理できる
    • 「速さ」ではなく「独立性」が重要。リリースしたいタイミングでそれぞれリリース出来る
  • AWS等の仮想化技術が普及したことでノードの管理コストが安くなってきた。
  • サービスがコーディング可能となった(アプリケーションではなく)。

サービス分割

  • サービスはどれくらいの大きさで切るべき?
    • 増やすと再利用性が高まる
    • 増えすぎるとノード間連携のオーバーヘッドが大きくなる
    • 適切なのは数百サービス x マルチノード = 数千ノード(先進的な企業でこれくらい)
  • サービスの粒度は「サービスによる」
    • ナノ: 0-3人月程度の単機能なAPI
    • マイクロ: 3-20人月程度の複数のAPI
  • サービスはドメイン単位にする?
    • ドメイン≒業務(利用者視点での関心事のカタマリ)
    • ドメインは実践してフィードバックで学んでいく「ボトムアップ」
    • 変更のタイミングが同じものは同じドメインに入れる方が良い
    • UI/ロジック/DAOのような技術特性での分割はするべきではない
    • 但し、技術的な限界はある
  • 利用者観点で分けていく時に分離しうる要素
    • ユーザーの種類、目的、プロセス、利用状況、ユーザー指向、ビジネス要件
    • フロントエンドとバックエンドを分離などはユーザーの種類が違うから、と考える
  • サービス分割は「分けられるものを分ける」だけ
    • 問題は分割時の技術制約をどうするか

横断的関心事の分離

  • 色々なサービスを横断的に見たい(認証、ログ、設定管理)場合は分離する
  • 認証認可
    • 共有データ => API化 => 専用サービス化
  • ログ
    • リクエストやサービス間通信にIDを発行してトレース出来るようにする
  • 設定管理
    • 環境に依存する設定情報を集中管理
    • 設定ファイルをネットワークから読み込んで動かす

データの分離

  • データは各サービスが管理する
    • データをサービス間で共有することは避けるべき
    • データの特製や種類に応じて洗濯
    • 不整合の許容範囲を決めることが重要
  • 共有データ => ビュー => トリガー/ストアド => ETL
  • 非同期には非同期、同期には同期のメリット/デメリットがある
  • イベントソーシング
    • データの状態を管理することからデータの変更などのイベントを共有する
    • CQRS/コマンドクエリ責務分離
  • メッセージング
    • データをどう統合するか
    • メッセージキューによる非同期化
    • 非機能要件を満たせるのがメリット
    • 非同期すると不整合が必ずある。これは技術で解決ではなく受け入れて運用でカバーする。Amazonは300円のクーポンをくれた。
  • サービス間のバージョン管理
    • バージョンに引きずられて変更することを避ける
    • 互換性を維持する
    • 複数のバージョンを保持する
  • 無停止デプロイ
    • Continues Deploy:コードがサービスになるまでの一連を自動化する
  • ブルーグリーンデプロイメント
  • カナリアリリース
    • ブルーグリーンにおけるカナリア = 最初に新バージョンにアクセスするユーザー
    • 何かの障害が発生したら切り戻す
  • 無停止スケールアップ
    • インテリジェントなルータが必要になる

サービスディスカバリとルーティング

  • レジリエンス(復元力)
    • マイクロサービスにおける可用性 = 障害が発生しても復元する力があるかどうか
    • 個別サービスの障害でシステム全体が停止しないようにする
    • コンポーネントが複雑になると「停止しない部分を積み重ねて停止しないシステムを作る」やり方には限界がある
  • サーキットブレーカー
    • 漏電を停止する仕組み
    • 自分の事は自分で守る: 障害発生時のパターン化を行い、異常処理対応を行う
  • タイムアウト、リトライ、デフォルト値、キャッシュ、例外処理など
    • Spring Retry

テスト戦略

  • サービス間のテストはどうするか
  • Test Doubles: モックをつくる
  • モックと実態の動きが違う場合がある
  • ダークカナリア
    • 本番環境上に開発者歯科アクセスできないテスト版をリリース
    • 本物を使ってテストする
    • Consumer-Driven Contract testing
    • このような動きをするべきだ、という内容を契約として他サービスに渡す
  • 本番環境のテスト
    • 障害注入テスト
    • Netflix's "Failure Injection Testing" (FIT)
    • レジリエンスの検証は本番環境でテストをする
    • たまにサーバーを落としてレジリエンスを確認する

チーム体制

  • コンウェイの法則
    • 「アーキテクチャは組織に、組織はアーキテクチャに従う」
    • チームは技術特性で分けている場合が多かった
    • これからはサービス構成で分ける
    • チームにサービスの自治権を与える
  • プラットフォームを管理するチームは必要
    • 横断的関心事の管理チーム

まとめ

  • マイクロサービスは機能別に好きなタイミングでリリースができることがメリット
  • 分割は難しくないが分割して起きる問題をどう解決するか、また受け入れられるか
  • サービスの分割は、いまからでもできる。今できないものは未来になってもできない
  • 不整合を受け入れる。一部のユーザーの不利益を受け入れることが大事
  • 現時点をマイクロサービスのLV1だと捉える
    • LV1: ほぼモノリシック
    • LV2: API連携
    • LV3: プラットフォームの整備、CI/CD
    • LV4: イベントソーシング、ストリーム処理
    • LV5: マイクロサービスに関する技術開発やOSSの提供

 

まとめ

マイクロサービスという、概念から話し出すと膨大な量になりそうなトピックを綺麗にまとめて、ユーザが聞きたいポイントに押さえて解説してくれた、という印象です。非常に実践的な内容でノウハウが詰まっていると思います。私も今関わってるプロジェクトで試してみたいと思います。