マイクロサービスTweetこんにちは。開発チームの松本です。年以前に作られたモノリスと、それ以降に作られたマイクロサービスのハイブリッド型として稼働しています。この数年、マイクロサービスを実践してきてつくづく感じているのは、全てのチームがマイクロサービスアーキテクチャスタイルの本質を理解した上で開発や運用を行うということの難しさです。「分散されたモノリス」なんていう話も聞きますが、これもやはり、本質を理解しないままマイクロサービスを実践した例です。つの特性に分解してその本質を述べた素晴らしいドキュメントです。これをチームの教育に使うことで前述の課題を解決しようと考えたのですが、ひとつ大きな問題がありました。記事を読み解くことが非常に難しいのです。英語の長文だという点もありますが、様々な技術トレンドやソフトウェア工学の知識などを背景に語られている個所が多い点にあるように感じます。そのため、一度読んだだけではドキュメントの各セクションのテーマや、書かれていることの因果関係を理解することが困難なようです。読み解いたものをドキュメントとして残すこと、となります。Design(進化的設計)それぞれの関係を図に表すと、次のようになります。これら全てを備えなければマイクロサービスアーキテクチャスタイルと言えないということではありません。マイクロサービスアーキテクチャスタイルを実践する多くのチームやソフトウェアシステムが持つ特性を抽出すると、このようになるということです。つの特性についてひとつひとつ読み解いていきます(翻訳ではありません)。読み解くためのヒントにはなるのではないかと期待しています。つの特性の中で、中核に位置します。おいてコンポーネントとは、関連する機能やデータの集まり(モジュラー)であり、その機能はインタフェースとして表現されます。このインタフェースを境界として、「コンポーネントを利用する側」と「コンポーネントを提供する側」にアーキテクチャを分離することで、カプセル化を実現します。カプセル化は、コンポーネントを提供する側によるコンポーネントの実装の変更や機能追加を、コンポーネントを利用する側とは独立して実施することを可能にするという恩恵をもたらしますが、これだけではまだいくつかの課題を抱えることになります。中では、「ライブラリによるコンポーネント化」と「サービスによるコンポーネント化」という二つのコンポーネント化方式を比較することで、ライブラリ方式における課題を明らかにし、サービス方式がより優れていることを解説しています。ライブラリとは、プログラムにリンクされ、メモリ内でファンクションとしてコールされるコンポーネントを指します。メカニズムを通して通信するコンポーネントです。ライブラリ方式でのひとつめの課題は、変更されたライブラリをアプリケーションに組み込むために、アプリケーション全体の再デプロイが必要になることです。これは、デプロイプロセスを鈍重にしてしまいます。一方で、サービス方式であれば、多くの場合、変更されたサービスのみをデプロイするだけで済みます。ライブラリ方式でのもうひとつの課題は、利用側の規律違反によって、カプセル化が解除されてしまう点にあります。これは皆さんも経験があるのではないでしょうか。意図的にせよ、仕様の理解の低さが原因にせよ、こういったことはよくあります。完全なカプセル化がサポートされていないようなプログラミング言語では、ライブラリ内部の非公開の変数や関数を利用されるようなケースがありえます。ライブラリのコードそのものを、利用側の用途にあわせて改変されたり、拡張されることもあり得ます。サービス方式のコンポーネントであれば、リモートコールのメカニズムによって、こういった問題を防ぐことができます。区別し、前者がより優れているとしています。内でのコンポーネントの定義の本質が見え、これが非常に重要な戦略であることに気付きます。upgradeable.(我々の定義ではコンポーネントとは、独立した交換とアップグレードが可能なソフトウェアの単位である。サービス方式によるコンポーネント化にも欠点はあります。粒度はライブラリのそれに比べ粗くなります。加えて、ネットワークによる問題を考慮した実装も必要となるため、コンポーネントの利用側にとっては、ライブラリ方式より少々扱いづらいものになります。Capabilities(ビジネスケイパビリティ中心の組織化)このセクションは体制についての話です。いう戦略に基づいてチーム編成が語られています。カプセル化が焦点でしたが、本セクションはモジュール性が焦点です。ソフトウェアシステム開発において開発チームをどのように編成するか、その切り口は様々です。複数のチームに分割することも、ひとつの巨大なチームとしてプロジェクトを運営することもできます。複数のチームに分けるにしても、どのような観点でチームを分割するかは様々です。チーム編成において重要な観点になるのが、ソフトウェアシステムに対する変更に際し、チーム間のコミュニケーションが大きくて複雑になるような組織構造は、ソフトウェアシステムの構造も複雑になり、プロジェクトにも悪影響を及ぼすという点です。コンウェイの法則です。チーム、サーバサイドロジックチーム、データベースチームの三つに分割して開発を進めると、小さな機能追加ですら、これら全てのチームが協力して対応しなければなりません。すると、チーム間での様々な調整(仕様、スケジュール、予算など)が発生してしまいます。三つのチームが抱える開発が、機能追加ひとつだけなら調整もそれほど面倒にはならないかもしれません。現実的には同時期に複数の開発を抱えているケースが多いでしょうから、チーム間での調整は更に面倒なことになります。なると、それぞれのチームは、チーム間の調整に時間を割くより、自分たちが受け持つコードベースにロジックを全て埋め込むことで、調整コストを削減しようと意識が働きます。結果、コンウェイの法則の通り、ソフトウェアシステムが、UI、サーバサイドロジック、データベースの三層でサイロ化します。このような、本来あるべきカプセル化が壊れ、ロジックが分散した状態は、ソフトウェアシステムにとって良い状態ではありません。マイクロサービスアーキテクチャでは、チームの単位とサービスの単位を揃えることで、この問題を解決します。このアプローチでは、チームやサービスの単位を、前述のようなソフトウェアアーキテクチャ的な視点ではなく、ソフトウェアシステムが対象とするビジネスが持つケイパビリティの視点で設計します。コマースビジネスを例にそのケイパビリティを挙げると、仕入れと販売、カタログ製作、マーケティング、注文管理、フルフィルメント、カスタマーサービスなどが含まれます。「業務」と言い換えた方が理解しやすいかもしれません。ビジネスにおける組織は、こういった単位で組織化され、それぞれの業務が遂行されることが多いでしょう。同様に、マイクロサービスアーキテクチャスタイルのチームもこういったビジネスケイパビリティを単位として組成され、それぞれが担当する領域の実装を担当します。そこにはユーザインタフェースもサーバサイドロジックもデータベースアクセスも含まれます。ゆえに、チームはクロスファンクショナルであり、その能力はフルスタックであることが求められます。ビジネスケイパビリティに基づく単一のチームが、関連する複数のサービスを管理することもあります。することで、チームが担当するビジネス領域の凝集度が高まり、それがチーム間の結合度を押し下げ、それぞれのチームの効率性を向上させることにつながります。モノリシックアーキテクチャでも、システム内部をビジネスケイパビリティ単位でモジュール化し、同じ単位でチームを分割することができます。ひとつのコードベースの中でケイパビリティによる境界を明確に分割し続けることは、現実的には困難です。境界を維持するために多くの規律(ルール)を設けたところで、いずれは規律違反によってカプセル化は崩れ、徐々にその境界が曖昧になります。「ライブラリ方式」で述べられている通りです。引き続き、体制の話です。運用面が話題となっています。あり、コンピュータ科学の博士であるワーナー・ヴォゲルス氏は、過去のインタビューでこう話しています。service.(デベロッパーに運用責任を与えることで、顧客と技術の両面において、サービス品質の大きな向上を得られた。伝統的なモデルでは、ソフトウェアを開発と運用の壁で分離していた。開発した人たちが、運用も行う。この考えによりデベロッパーは、ソフトウェアの日々の運用に接することになる。この、顧客とのフィードバックループは、サービス品質の改善に不可欠だ。モデルとは、インタビューでも述べられている、開発と運用が分離された体制です。開発が完了するとチームが解散し、システムが運用チームに引き継がれるモデルだと考えてください。モデルがマイクロサービス流のやり方です。しての体制のことで、プロダクトのライフサイクルを通してチームが一貫して責任を持ちます。サポート業務の一部も担います。することで、チームは「顧客のビジネスケイパビリティの強化を如何にして支援していくか?」という視点を得て、これが運用の中心となります。おけるビジネスケイパビリティと、このプロダクトという考え方は、深い関係性があります。ビジネスケイパビリティ中心チームを次のように説明しており、前述のワーナー・ヴォゲルス氏の話と同様の考えに基づいていることが読み取れます。end-to-end.(ビジネスケイパビリティ中心チームは、「考え、開発し、運用する」チームだ。彼らは、自らの開発物のテストやデプロイ、サポートを他のチームに引き渡したりはしない。担当領域全体の問題を、自分たちで抱える。ある通り、個々のマイクロサービスは、サービスとしてコンポーネント化されたもので、関連する機能やデータの集まり(モジュラー)です。みやすさの点で好ましいモジュールは、凝集度(cohesion)が高く、結合度(coupling)が低いものです。このセクションはマイクロサービス間のコミュニケーション方式について書かれているのですが、そこでの方式選択は、モジュール性能の向上を目的としています。中の次の文章に、それが表れています。possible(マイクロサービスとして構築されるアプリケーションは、可能な限り、それぞれが分離され、凝集されていることを目指している)スマートエンドポイントとは凝集度の高いサービスを指し、ダムパイプとは結合度を下げるために取るシンプルなコミュニケーション方式を指しています。パイプラインに例え、前者をフィルター、後者をパイプとしています。対して、オーケストレーションと呼ばれる、コミュニケーションメカニズム自体にスマートさ(かしこさ)を置いた方式は、様々な機能を兼ね備えた中央制御型のコミュニケーション方式(ダムパイプに対してスマートパイプ)です。それゆえに、サービスの凝集度が低く、サービス間の結合度が高くなります。実現は困難となってしまいます。従って、マイクロサービス間のコミュニケーション方式には、中央制御型のオーケストレーションより、シンプルなコレオグラフィーが適しています。コレオグラフィーは、オーケストレーションのような中央制御型ではなく、コミュニケーションネットワーク上の各ノード(つまりサービス)が、あらかじめ決められた別のノードに対して直接通信を行います。このように、コレオグラフィーは仲介役(ブローカ)となるサーバーを中央に置かないため、単一障害点がなく、メッセージングの信頼性も向上します。ような軽量のメッセージキューを介した非同期通信です。この軽量なメッセージングプロトコルは、サービスからサービスへのメッセージ送受信のルーターとして機能することで、メッセージバスとして働きます。なりますが、これは「標準化」と表現した方がわかりやすいでしょう。ソフトウェアシステム開発において技術面やプロセス面を標準化する目的は、属人性を最小化し、成果物の品質を上げ、生産性を上げることです。標準化で定められた方式が、チームの直面する課題に対して最適なソリューションにならない場面も多々あります。いったケースでは標準化の強制が逆に足かせとなって、チームの開発パフォーマンスを貶めてしまいます。マイクロサービスアーキテクチャのように、システムが個々のサービスとしてパーティション化されていると、標準化よりも良いやり方を選択できます。呼び、チームへの権限移譲による独立性の向上として解説しています。使ってシンプルなレポートページを作りたい?頑張って。コンポーネント開発に?いいね。コンポーネントで使用しているデータベースを、読み取りに適した別のものに交換したいって?それに適したミドルウェアがあるよ。語られているように、マイクロサービスアーキテクチャにおけるサービスとはコンポーネントであり、カプセル化されています。contract)です。一方で、カプセル化された中身をどのように作るかは、それに最も適した方式をチームが選択すれば良いだけです。