最近、身の回りで「マイクロサービスを導入したいがどうすればいいか」、あるいは「導入を検討している」「導入したので実施できる人がほしい」という話を聞く機会が増えました。
私はこれに対し「マイクロサービスはやりすぎなので止めたほうがいい」と回答することが多いです。それについて説明したいと思います。

この記事は「私はこういうスタンスである」というのを回答しやすくするために書いているため、継続的に追記・ブラッシュアップしていく予定です。

マイクロサービスの導入を見送るべき見せかけのメリット

どういう理由でマイクロサービスを検討しているかと深堀りすると、次のような理由が返ってきます。

  1. デプロイ時の障害や停止時間を減らしたい
  2. サーバ負荷を分散させたい
  3. ソースコードがスパゲティになっているので解きほぐしたい
  4. 予測できない将来の改修に備えたい
  5. 今風の技術を取り入れることで人材採用のセールスポイントにしたい

これらに対し、マイクロサービスはソリューションになります。しかし、マイクロサービスでなくともソリューションがあります。

  1. デプロイ時の障害・停止時間はブルーグリーンデプロイメントやDevOpsで回避できる
  2. サーバ負荷はオートスケーリング可能なクラウドサーバとアプリケーションで対応できる
  3. スパゲティなソースコードは継続的なリファクタリングで改善できる
  4. 予測できない将来への対応はアジャイル開発で順応できる
  5. 上記をそれぞれ実施できることは十分に人材採用のセールスポイントとなる

それぞれに改善施策があります。そして、マイクロサービスは上記のすべてとそれ以上のものを要求します。つまりマイクロサービスがソリューションなのではなく、複数のソリューションの組み合わせたものがマイクロサービスなのです。

マイクロサービスを見送るべきデメリット

マイクロサービスの本質的なメリットは「分散コンピューティング」によるものです。分散することで大きなチームを小さな単位に分け、大きなシステムを小さなシステムに分割し、開発単位を小さく分割し、サーバ負荷を小さく分けられます。つまり分割統治です。

分散コンピューティングは過去にもCORBAやXML-RPC、SOAP、SOAなどが実装・提唱されています。今でも使われてはいます。しかし、それらの活用よって上手くシステムを作り上げたという美談はあまり聞かなくなりました。

分散コンピューティングは、次の実施上のデメリットがあります。

  1. 外部設計の困難:サブシステム間のインターフェースすり合わせや異常系処理手順の取り決めなど、外部システム連携固有の設計上のやり取りが発生する
  2. 内部設計の困難:データベースも分割されるため、RDBのトランザクションやロールバック、JOINなどの機能を活用できない。また、分散データベースにおける整合性確保の困難さが発生する
  3. 実装の困難:開発環境の維持・メンテナンスが煩雑になり、環境更新時に開発者間での統一の難しさが発生する。また、開発端末に性能を要求するため、開発効率が落ちるかハイエンド端末への全員分買い替えが必要になる
  4. テストの困難:結合テストがモジュール結合ではなく外部システム連携テストになり、不具合検出時の修正が複雑になる
  5. リリースの困難:うまく作らなければ各システムのリリース順番に依存性が発生し、時には全システムを止めるメンテナンスタイムが必要になる
  6. 運用の困難:障害発生時にどのサブシステムでエラーが発生したかわかりにくい

それぞれに解決策はありますし、モノリシックにも困難はあります。しかし、困難への対処方法はモノリシックのほうに多くのノウハウがあります。事例も遥かに多いです。分散コンピューティングの困難さに比べると、そのスキルセットを持った開発者の調達はモノリシックのほうが容易です。

コンピュータの歴史は「分散」と「集中」を繰り返しています。マイクロサービスもその流れのひとつに過ぎず、銀の弾丸にはなりえません。

マイクロサービスのメリット:障害の平準化とチーム数のスケーリング

マイクロサービスの世界的な流行には、技術的側面ではなく経営的側面が大きいと思います。マイクロサービスを採用している代表的なwebサービスとして、NetflixとAmazon Web Servicesがあり、ともにマイクロサービスの特徴が経営面に活きています。

Netflixはその特性上、収益が動画コンテンツ提供に依存しています。webサービスがメンテナンスに入ればその時間だけ機会損失が発生し、その被害額は計り知れません――いや、むしろ時間比例の”算出可能な”被害額が関係者へのプレッシャーとして襲いかかります。作業者の年収が秒で吹き飛びます。
そのような収益構造を持った状態ですので、マイクロサービスによって「障害の可能性と影響が分散される」構造を手に入れることはリスクヘッジのメリットがあります。また、カオスエンジニアリングできるほどに1つの障害発生の影響が平準化されています。

Amazon Web Servicesはマイクロサービスを組み立てるための基盤サービスであり、またAWS自身がマイクロサービスで作られています。
AWSは当初「シンプル」や「エラスティック」をサービス名に付けていましたが、いまやシンプルではなくエラスティックとも言い難いほど先鋭化されたサービスが大量に並んでいます。
各サービスのチームが10人程度までであり(two-pizza rule)、チーム間連携を疎にできていることが効いています。多くのチームを立てても管理上の問題が発生しにくく、これほどの規模のサービス群を支えることができます。

さて、あなたのシステムはサブシステム停止の影響を平準化できるほどの規模になるでしょうか? また、多数のチームを並べるほどの規模になるでしょうか?

日本におけるマイクロサービス事例は先行事例としにくい

上記2つのサービスは世界的かつ極大規模なものでした。一方、日本のマイクロサービス導入事例は次のものが有名です。

これらはそれぞれ事例を登壇発表しており、最終的にメリットを得られているとしています。

しかし、クックパッドはマイクロサービス導入に一度失敗をしており、成功事例として出されているのは二度目のものです。
メルカリはマイクロサービス導入を2017年から継続しており、現在も作業中です。そこにかけている人件費も相当なものでしょう。
ダイソーも一度導入に失敗していることを引き合いに出しており、その反省点を活かしてのことです。

それぞれ、システムが大きくなってからの導入です。システムが小さいうちは問題ではありませんでした。また、大きくなったからこそ費用を掛ける価値があります。
大きくならないうちに先回りしてやっておけば、コストはより小さくできたかもしれません。しかし、システムが小さいうちはそのメリットも小さいです。障害の被害額は小さく、サーバ負荷も低く、ソースコードも把握しやすく、開発もアジャイルにしやすいです。

つまり小さなうちのマイクロサービス導入は先行投資です。「小さく産んで大きく育てる」の逆を行く方法です。では、投資先はマイクロサービスがベストかどうか? CI/CDやアジャイル開発など、より小さく導入しやすいソリューションがあります。

規模が小さなうちにマイクロサービスを投入するのは「ベンチャー企業が設立当初から上場向け監査を受ける」ような印象です。規模を確保する絶対の自信があればそれでも良いですし、上場前からガバナンスなどのメリットを享受できます。しかし、多くの場合は上場できずに終わります。

導入するならストラングラーパターンの検討を

社内事情などからマイクロサービス導入を避けられないこともあるでしょう。その場合はストラングラーパターンが良いでしょう。新機能や改修機能からマイクロサービスにしていくことで、モノリシックの苦しみから逃れつつ漸進的に事を進め、マイクロサービスのメリットを最速で享受する方法です。

先行事例は上記メルカリです。何年もかかるかもしれません。途中でサービスが終了する可能性すらあります。それでも、中途半端な共存状態でも保守する成算を立てることができれば、有力な選択肢になります。方向性は次のスライドに詳しいです。

https://www.graat.co.jp/blogs/ck0nwv2m3ctzj0830xweica5d

参考リンク:マーチン・ファウラー氏の警鐘

マイクロサービスという名前を最初に使い始めた一人がマーチン・ファウラー氏ですが、氏自身はマイクロサービスについて「マイクロサービスのトレードオフ」としてデメリットを警鐘しています。
https://postd.cc/microservice-trade-offs/

また、「マイクロサービス・プレミアム」という記事が採用基準の参考になるでしょう。英語ですが、google翻訳で十分に意図はつかめます。
ここでいう「プレミアム」は特別なグレードの意味ではなく、割増料金や追い銭のことです。マイクロサービスはコストを要求します。
https://www.martinfowler.com/bliki/MicroservicePremium.html

マイクロサービスの前提条件についても述べています。クラウドに始まる流行りの技術を組み合わせてようやく実現できることがわかると思います。
https://www.publickey1.jp/blog/14/post_246.html