モノリスから始めない
… 目標がマイクロサービスアーキテクチャである場合
2015年6月9日
ここ数ヶ月、マイクロサービスアーキテクチャを成功させる唯一の方法は、まずモノリスから始めることだと何度も耳にしました。サイモン・ブラウンの言葉を言い換えると、構造化されたモノリスを構築できないのであれば、なぜ構造化されたマイクロサービスのセットを構築できると思うのでしょうか?この議論の最近の、そしていつものように非常に説得力のある表現は、このサイトのマーティン・ファウラーによるものです。以前の草稿にコメントする機会があったので、このことについて考える時間がありました。そして、特に普段から意見を共有している彼や、他の見解を共有している人たちが彼に同意しているように見えたため、考えました。
私は、モノリスから始めることは、通常、まさに間違ったことだと確信しています。
新しいシステムの構築を開始するときこそ、それを細かく分割することを考えるべき時です。私は、サム・ニューマンが表明したように、これを先延ばしにできるという考えには強く反対します。彼は、私が95%の時間は同意する人です。
既存の「ブラウンフィールド」システムを分割する方が、新しい「グリーンフィールド」システムで前もって分割するよりもはるかに簡単だと私は確信しています。作業できるものがたくさんあります。調べることができるコードがあり、システムを使用および保守する人々に話を聞くことができます。また、「良い」状態がどのようなものかも知っています。変更を加えることができる動作中のシステムがあるため、意思決定プロセスで何かを間違えた可能性がある場合や、過度に積極的になりすぎた場合をより簡単に把握できます。
-- サム・ニューマン
ほとんどの場合、既存のモノリスをこのように分割することは、不可能ではないとしても、非常に困難でしょう。(常に不可能というわけではありませんが、それは今後の投稿のトピックです。)システムを構築するドメインを、分割を試みる前に非常によく知っておく必要があるという点では、共通点があります。私の見解では、理想的なシナリオは、既存システムの2番目のバージョンを構築している場合です。
実際に構造化されたモノリスを構築できるのであれば、そもそもマイクロサービスは必要ないでしょう。それでOKです!私はマーティンの意見に完全に同意します。そうする明確な理由がない限り、システムに余計な分散の複雑さを導入すべきではありません。
(では、良い理由とは何でしょうか?たくさんありますが、私にとって最も重要なのは、大規模システム内で個々のパーツを迅速かつ独立してデリバリーできるようにすることです。私の見解では、マイクロサービスの主な利点は、システムの異なる部分間に越えにくい境界を設けることで並列開発を可能にすることです。こうすることで、間違ったことをする、つまり、接続すべきでない部分を接続したり、接続する必要のある部分を緊密に結合したりすることを難しくします(少なくともより難しくします)。理論的には、モノリシックアプリケーション内で明確なルールに従い、明確な境界を確立する規律さえあれば、マイクロサービスは必要ありません。実際には、そうなることは非常にまれであることがわかりました。)
モノリスの中に、抽出されるのを待っている、うまく分離されたマイクロサービスが多数潜んでいると仮定したくなるかもしれません。しかし実際には、計画的であれ計画外であれ、多数の接続を作成することを避けることは非常に困難です。実際、マイクロサービスのアプローチの要点は、このようなものを作成することを難しくすることです。
しかし、モノリスから始めると、パーツは互いに非常に緊密に結合します。それこそがモノリスの定義です。パーツは、すべてが使用するプラットフォームの機能に依存します。同じライブラリを使用しているため共有されている抽象化に基づいて通信します。同じプロセスでホストされている場合にのみ利用できる手段を使用して通信します。そして、これらは技術的な側面にすぎません!それよりもさらに悪いことに、パーツは(ほぼ)自由にドメインオブジェクトを共有し、同じ共有永続モデルに依存し、データベーストランザクションがすぐに利用できると想定しているため、補償の必要はありません… 物事をリファクタリングしたり、移動したりするのが簡単であるという事実そのものが、単一のプロジェクトのIDEのビューで便利であるため、再び分割することが非常に困難になります。既存のモノリスを個別のパーツに分割することは非常に困難です。
私は、開始するときは、構築するサブシステムについて考え、それらをできる限り相互に独立して構築するべきだと強く信じており、最近のいくつかのプロジェクトからの経験がこれを裏付けています。もちろん、自分のシステムがこれを正当化するほど大きいと考える場合にのみ、これを行う必要があります。あなたとあなたの同僚の1人が数週間かけて何かを構築する場合、そうする必要がない可能性は十分にあります。
しかし、システムをより小さなパーツに分割し、それらのそれぞれを、独自の開発、デプロイ、デリバリーサイクル、(そして可能性として)独自の内部アーキテクチャを持つ、明確に分離された個々のシステムとして扱うアプローチから始めることは、そもそもシステムをデリバリーするのに役立つ非常に強力なコンセプトです。
では、これを裏付ける実際の経験はあるのでしょうか?はい、最近関与したいくつかのシステムが、このコンセプトが機能することを示しました。ただし、私が話していることが、一般的なマイクロサービスよりも大きい可能性が高いという事実を許容する必要があります。最も顕著な例はOtto.deです。これについては、彼らの技術リーダーと講演を一緒に行いました(また、彼らの主任アーキテクトの1人によるこの素晴らしい記事で読むことができます)。しかし、他にもかなりの数の例があり、自分が構築するドメインを本当に、本当に十分に知っているとすれば、このアプローチを使用してシステムを構築し始めるのは良い考えだと確信しています。
しかし、この議論から学ぶべき別の教訓があります。それはより一般的な教訓です。あまりにも単純で明白なアーキテクチャのレシピには注意してください。このレシピ、つまり、ドメインを個別の独立したパーツに分割することから始めるというレシピも例外ではありません。モノリスが好ましい場合もあれば、そうでない場合もあります。マイクロサービスのアプローチを使用して構築することを決定した場合は、個々のパーツでローカライズされた意思決定を行うのがはるかに簡単になりますが、これを可能にする境界自体を変更するのははるかに難しくなることを認識する必要があります。小さなリファクタリングは簡単になりますが、大規模なリファクタリングははるかに難しくなります。
アーキテクチャに関する議論では常にそうであるように、個々のケースごとに自分で決定する必要があるという事実を避けることはできません。
謝辞
この投稿の以前のバージョンに対してマーティン・ファウラーが提供したコメントと、過去数週間のこのトピックに関する継続的な議論に感謝します。もちろん、彼がこのサイトで公開することを許可してくれたことも非常に嬉しく思っています。私の同僚であるダニエル・リューブケ、オリバー・ウルフ、アレックス・ホイジングフェルド、ティル・シュルテ・コエルネ、アンドレアス・クルーガー、エバーハルト・ウルフも貴重なフィードバックをくれました。グラフィックを作成してくれたローマン・シュトラングホーナーに特に感謝します。
参考資料
- ステファン・ティルコフのブログ
- 効果的なマイクロサービスアーキテクチャを設計する方法について語るステファンの動画。
- モノリスと、それらを早期にサービスに分割することの重要性に関するステファンの2013年のブログ記事
- ローマン・シュトラングホーナーのインフォデッキでは、マイクロサービスとしてアプリケーションを構造化する概要(自己完結型システムという名前を使用)を示しています。ローマンは、innoQのステファンの同僚です。