野次馬エンジニア道

野次馬な気持ちでプログラミングをあれこれと綴ります

Building Microservices

2016年もあと少し。毎年恒例オライリーのカレンダー欲しさに今年も本を購入。

f:id:notta55:20161218172556j:plain

大分前に読んだが内容をまとめていなかったので気になったところをメモ書き。

マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャ

マイクロサービスとは小規模で自律的なサービス。自律的とは、単独でサービスのデプロイを行いAPIを介して利用できるような状態のことを指している。

翻訳だと凝集性ということばが出てくる。原文だとCohesion。関連するコードが集まるような状態のこと。結合度と並べて比較される。結合度が高いものは凝集度も低い。

情報工学においてモジュール内のソースコードが特定の機能を提供すべく如何に協調しているかを表す度合いである。 Wikipedia 凝集度 - Wikipedia

マイクロサービスの利点とは?

  • 技術的異質性
  • 回復性
  • スケーリング
  • デプロイの容易性
  • 組織面の一致 (原文だと Organizational Alignment) - 重要なコンウェイの法則について
  • 合成可能性 (原文だと Composability) - これだけだと何のこっちゃという感じだが、

組織が、狭いチャンネルの観点での考え方からより全体的な顧客エンゲージメントの概念に移っているので、それに遅れてついて行けるアーキテクチャが必要です。

P9. より

すっきり。 - 交換可能性にするための最適化 (原文だとOptimizing for Replaceability) 、早い話が、置き換えコストの話。

原則とプラクティス・ガバナンス

2章の進化的なアーキテクトの中であった原則とプラクティスの考え方。原則を確実に実行するためのプラクティス。プラクティスは時を経て変わるかもしれないが原則は変わらない。本文中で紹介されていた例。このようなレベル分けが整理するには有効。

ガバナンスが意味するところ

ガバナンスは、利害関係者のニーズ、状況、選択肢を評価し、優先度順位付けと意思決定を通じて方向性を設定し、合意した方向性や目的に対する実績、順守、進捗の監視を行うことで企業の目的が達成されるようにすることです。

  • COBIT5 P.29より

自律した小さいサービスを複数開発するがゆえにガバナンスは特に重要となる。

境界づけられたコンテキスト (Bounded Context)

これもピンとこない。

私が好きな境界づけられた別の定義は、「明示的な境界によって強制される特定の責務」です。

P.35より

と本文中リンクを一つ紹介している

blog.sapiensworks.com

コンテキストは特定の責務のこと。境界づけられたコンテキストとはほぼIT部門や経理部門のような組織のことを指している。責務とはIT部門であれば、システムやソフトウェアの面倒を見る(責務がある)ということで、経理部門であれば給与を管理するなどである。給与の計算ソフトに何か不具合があったときに、直接経理部門の人がデバッグしたりしない。またIT部門のなかが開発部門とサーバなどのインフラ管理にわかれていることも経理の人には関係ない。ではこの二つの部門がどのように協業するのか。このリンクの例ではそれぞれの部の担当者に加えてIT部門のManagerが登場する。新機能の追加や不具合の追加など、すべてManagerを通す。

つまり二つの境界づけられたコンテキストは双方に違いの中を知る必要がなく、これら二つの境界づけられたコンテキスト通しが共通のオブジェクトを一方へ直接渡す、もしくは両者が話せる話せる特別なアダプターを用いることになるということである。少しイメージが湧く。

設計観点でのサービスとしての責務はあるが、やはり組織やチームが面倒を見る範囲という実体に則った切り口というのが自然と言える。

トランザクション境界

モノリシックなデータベースだとすべての作成や更新は一つのトランザクション境界(開始と終了)内で行われるが、データベースを分割するとそうではなくなる。その問題に対処するために後でリトライするか補正トランザクション(Compensating Transaction)を発行して操作全体の中止をするか。いずれにせよ一貫性を保ちたい対象が大きければ難しい問題となる。

分散トランザクション - 2相コミット(Two-phase commit)

本文中に出てくるトランザクションマネージャの話。ネットワーク境界を越えて通信する複数の異なるシステムに対して一貫性を保つ。 少し古い記事だがここのシーケンス図がわかりやすい*1

仕組みは簡単。投票フェーズ(コホートとも呼ばれる)で全参加者がOKだったらコミットするように指示するというもの。 f:id:notta55:20161218150803p:plain

トランザクションマネージャはダウンしない、コミット指示があるまで各参加者は停止しているため、投票フェーズで障害があると参加者はブロックされるなどいくつか制限がある。

バッチAPI

DBではなくAPI中心にした場合にレポーティングのためなどに全データの取得などのユースケースが問題になる。

顧客サービスはBatchCustomerExportリソースエンドポイントのようなものを公開できます。呼び出し側システムはBatchRequestをPOSTし、おそらく全データを含むファイルを配置できる場所に渡します。顧客サービスはHTTP 202レスポンスコードを返し、リクエストを受け付けたものの未処理であることを示します。すると呼び出し側はシステムはリクエストが実行されたことを示す201作成済み状態を受け取るまでリソースをポーリングし、それからデータを取得できます。

P.113より

他にはデータを別のレポートのDBに定期的に投入するデータポンプという仕組みも紹介されている。

CAP定理

分散システムに互いにトレードオフとなる3つの事項がある

  • 整合性 (一貫性、consistency)
  • 可用性(availability)
  • 分断耐性(partition tolerance)

全てを満たせないのは数学的に証明されている。例えば整合性を犠牲にして可用性を維持するシステムは結果整合性があるという。この場合はAPを選んでいることになる。分散システムの場合ネットワーク上で動作させなくてはならないのでCAという組み合わせはない。整合性はあるけれども構築やスケーリングが困難なCPという選択肢もある。複雑なのはそれがサービス単位で選ぶよりも細く考慮が可能なところ。

整合性がないか可用性がないかはオールオアナッシングではない、ということがあります。多くのシステムではさらに細かいトレードオフが可能です。例えば、Cassandraでは呼び出しごとに異なるトレードオフを選ぶことができます。

P.273より

コンウェイの法則

組織とアーキテクチャが一致すべきという考えで、それの根拠となる論文*2からきている。

システム(ここでは単なる情報システムよりも広く定義されたシステム)を設計するあらゆる組織は、必ずその組織のコミュニケーション構造に倣った構造を持った設計を生み出す。

P.223

チームにそのチームが担当するシステムを所有、運用させ、ライフサイクル全体を管理させる、そのために必要であれば組織構造をも変えてしまうという例が紹介されている。さらに地理的な要因やコミュニケーションの経路も同様に設計に重要なインパクトを与える。

まとめ

12章にあるまとめ(原文では、Bringing It All Together)。

  • ビジネス概念に沿ったモデル化 (Model Around Business Concepts) -
  • 自動化の文化の採用 (Adopt a Culture of Automation) たくさんの可動部を扱うために高度な自動テストと継続的なデリバリが必須なところ
  • 内部実装詳細の隠蔽 (Hide Internal Implementation Details) - モデル化とAPI
  • すべてを分散化 (Decentralize All the Things) - これはシステムのことではなく、意思決定と制御を可能な限りチームに委譲することを指している
  • 独立したデプロイ (Independently Deployable)
  • 障害の分離 (Isolate Failure) - アンチフラジャイルの概念を念頭に置いて、障壁やサーキットブレーカーなどを使って副次的な影響を最小限にする
  • 高度な観測性 (Highly Observable) - セマンティック監視や合成トランザクションの導入を通して統合的な監視を行う

最後に書きながらあれもこれとなった。この本はテンコ盛り。

感想

この本の帯にマーチン・ファウラー*3は「マイクロサービスへの道は、注意深く進まないと痛みを伴う罠がある」というコメントを寄せている。それでも構築できれば他を圧倒する優位性があるのだと思う。本書によるとその道のりはまさに旅。先人の知恵が凝縮されたそのガイド本として読み応えがある本だった。