AWS Startup ブログ

スタートアップのためのマイクロサービス入門

こんにちは、スタートアップ ソリューションアーキテクトの松田 (@mats16k) です。

以前「スタートアップのためのコンテナ入門 – Kubernetes 編」を出した際に記事内で、マイクロサービスやサービスメッシュにふれる機会がありました。今回は AWS でデベロッパーアドボケイトをしているトリ氏 (@toricls) にマイクロサービスについて記事を寄稿いただきました。

※ 本記事は Software Design 2020年7月号 に掲載された「スタートアップのためのAWSテクノロジー講座 – マイクロサービスのあるべき姿と特徴を知る」からの転載、改修版です。

目次

 

マイクロサービスにはコンテナが必要なのか?

私は AWS のコンテナサービスチームにおいてデベロッパーアドボケイトというロールで仕事をしていますが、日々の業務の中でさまざまな企業のエンジニアと課題解決の方法や技術選定についてディスカッションを行うことがあります。

最近お客様からの相談が増えているものの1つに マイクロサービス があります。「自社のサービスのソースコードが肥大化してきたから、分割して開発効率を高めたい」「マイクロサービス化するのが現代的なトレンドらしいですが、〇〇から手をつけるべきでしょうか」など、相談の中身はさまざまですが、マイクロサービス化の推進にはコンテナの導入が必須と認識されている方も多くいらっしゃいます。「コンテナを使おうと思っている」とおっしゃるお客様にその理由を聞くと、「マイクロサービスをやりたいから」といった回答が返ってくることも多々あります。

マイクロサービス化とコンテナ導入は本来、性質を異にするものです。たとえば、マイクロサービス化を推進している企業の1つとしては Amazon が挙げられますが、同社はモダンコンテナ (*) が流行するずっと前、マイクロサービスという言葉の誕生以前からマイクロサービス化を推進してきました。

* Docker 以降の現在の Open Container Initiative (OCI) に至るコンテナを、それ以前のものと比較して「モダンコンテナ」と表現しています。

サービスの分割が進んだ現在においても、使用されているアーキテクチャはチームごとに多種多様です。自分たちのサービスを実現する環境として、Amazon EC2 に代表される仮想マシンをおもに用いるチームや、コンテナを活用しているチーム、AWS Lambda のようなサーバーレス技術を積極的に使うチームなど、開発・運用するサービスの要件や特性に応じて適切なアーキテクチャとコンポーネントを採用しています。さらに重要なことに、それぞれのチームの技術スタックはサービスの状況や世の中の技術の進化に合わせて継続的な変化を繰り返しています。

Amazonではチームがそれぞれに必要最適な技術選定をしている

これは、利用する技術とマイクロサービス化の成否に直接の関係がないことを示す代表例と言えます。むしろ「マイクロサービス = コンテナ」という考え方は、自分たちの技術選定の可能性を狭めます。本来、それぞれのチームが他のチームが採用した技術や実装に影響を受けることなく、自らのサービスに必要な技術を選定できることこそ、マイクロサービスの重要なメリットの1つであったはずです。「マイクロサービスにするならば、どのチームも〇〇を利用しなければならない」という考え方に強く依拠することは、マイクロサービスそのものの価値を否定しかねない自己矛盾です。

 

サービスメッシュは本当に必要なのか?

マイクロサービス化の推進には、マイクロサービスならではの課題の解決が必要になります。例えば、代表的なものとして次のような課題が挙げられるでしょう。

  1. マイクロサービスにおいては呼び出し先サービスの位置は一定ではない(割り当てられる IP アドレスを事前に知ることができない)ため、サービスディスカバリを行う必要がある
  2. API 呼び出しが一時的に失敗した場合、リトライが必要になる
  3. API 呼び出しが継続的に失敗しているならば、サーキットブレイカーによってその処理を中断しなければならない
  4. サービス間通信の可観測性を高めるには、ログ・メトリクス・トレースといった情報の取得が必須である

こうした課題の解決方法の1つがサービスメッシュです。各サービス間の通信を全てプロキシ経由にし、ときにはアプリケーションコンテキストの外部との通信にもプロキシを噛ませることで、上記一連の処理が透過的に実現されます。マイクロサービスの隆盛に伴い、サービスメッシュの導入も必須であるかのように謳われることが多くなりました。

サービスメッシュ – サービス間通信の信頼性と可観測性の実現

ですが、「この技術を必要とするケースはそう多くない」と考えています。もちろん、サービスディスカバリやリトライといった分散システムに必須の課題を解決する仕組みが不要であると言いたいわけではありません。重要なのは、その課題解決の役割を担うのが サービスメッシュである必然性はない ということです。

共通ライブラリなどによる実現方法と比較して、サービスメッシュは「ビジネスロジックとしての興味(サービス)」と「インフラや運用としての興味(プロキシ)」を疎結合にし得るという利点があります。しかし、あなたが所属している組織はそもそも、その利点を必要とするような組織構造をしているのでしょうか。そうではない場合、サービスメッシュの導入はかえって開発・運用コストの増大を招いてしまう可能性があります。

* サービスメッシュについては下記動画「サービスメッシュは本当に必要なのか、何を解決するのか | AWS Summit Tokyo 2019」も合わせてご覧いただくと理解を深められるかと思います。

 

「マイクロサービス」という言葉の功罪

マイクロサービスは単なるシステム分割とは異なります。当然のことではありますが、マイクロサービスという言葉が生まれるはるか前から、多くの企業がマシンリソースの有効活用や影響範囲の局所化を目的としてシステム分割を行なってきました。マイクロサービスという新たな言葉による定義が求められた背景には、それが今までのシステム分割とは性質を異にするものであったという事実があります。

新たな傾向が生まれてきたのは2000年台前半からでしょうか。それまでとは違った切り口や手法で、システムを分割する企業が増えてきました。彼らは分割されたシステム群の独立したデプロイを目指し、それにより高速なシステム開発とデリバリーを実現しようとしました。システムはそれぞれが API を公開し、そのやりとりに HTTP ベースの通信を用いる手法を導入したのです。また、システムを技術的に分割するだけでなく、それらのシステム間の疎結合性を継続的に維持するために、各サービスチームが独立した意思決定を行えるような組織作りを進めました。その手法がこれまでの単なるコンポーネント分割とは異なっており、多くの識者がこれに名前をつけようと試みた結果、市民権を得た名前が「マイクロサービス」でした。

高速な開発を目的として今でもよくとられる手法に1つに、いわゆる「共通ライブラリ」があります。システムを分割して独立したデプロイメントは可能にしつつも、それらのシステムで共通する処理に対しては共通ライブラリを実装して組み込む、というこの手法は、当然ながら現在でも有効な手段の1つです。

では、彼らが共通ライブラリ方式だけではなく新たなアプローチをとった理由は何だったのか。それは、各チームの独立性と、それによる組織のスケーラビリティの確保にあります。各サービスチームが自分たちの課題を高速に解決し、サービスを成長させていくためには、各チームが独立した意思決定を行えるよう、他チームとの依存関係を断ち切る必要がありました。

コンウェイの法則 (*)」と呼ばれる有名な論文・主張があります。これは「ある組織が作り出すシステム構造は、不可避的にその組織自身のコミュニケーション構造のコピーとなる」というものです。この趣旨に沿って考えれば、システム開発に多くの人間のやりとりが必要となる組織ではシステム構造にも多くの依存関係が生まれます。逆に言えば、依存関係の少ない組織からは依存関係の少ないシステム構造が生まれます。
* 参考: How Do Committees Invent? by Melvin E. Conway

コンウェイの法則(図はコミュニケーション構造が割られていない場合に、モジュールが密結合している例)

この前提をベースとし「組織構造を機能ごとに明確に分割し、各チームに独立した意思決定を許容すれば、システム間の依存関係は抑えられる」という発想が生まれました。これは「逆コンウェイの法則」と呼ばれます。これを実現しようと試みたのが、たとえば Amazon であり Netflix です。そして、これらが結果として、あとからマイクロサービスと呼ばれるようになりました。

逆コンウェイの法則

では、そもそもマイクロサービスという手法は、すべての企業にとって必要なものなのでしょうか。私は必ずしもそうではないと考えています。マイクロサービスが真に、現時点での自社にとって必要なのかどうかについて、深く検討してみるべきです。

マイクロサービスの推進が機能している企業は、前述のように機能ごとにチームを分割した上で、各チームに意思決定を委譲しています。これにより、チーム間の煩雑な調整作業に時間を奪われることなく、スピード感を持った開発とデリバリーを実現できるようになります。

それぞれのチームは、各サービスを呼び出す際の公開されたインターフェースとその仕様のみを知っており、別のチームがどのような体制で開発しているのかを知りません(知る必要もありません)。インターフェースよりも後ろにあるアプリケーションの実装内容は、他のチームから完全に隠蔽されています。仮にあなたが他チームのインターフェースに仕様とはことなる挙動を見つけたとしましょう。そしてあなたには他チームのコードリポジトリをみる権限があったとします。だとしても、あなたはその実装に合わせて自分の呼び出し側のコードを書き換えるようなことをしてはいけません。バグチケットを起票し、機能に責任を持つチームにその実装が仕様を守るように修正を依頼すべきです。

チーム間の関係性が密結合になってしまう行動はすべて、マイクロサービスにおけるアンチパターンと言えます。マイクロサービスは本来、組織間の関係性を疎結合にすることで、システム開発の自立性や開発・デリバリー速度を高めることが目的と言えるからです。

 

マイクロサービスが必要な企業は極めて限定的である

マイクロサービス化は本質的には「逆コンウェイの法則」によって、組織とシステムの双方に独立性とアジリティをもたらす手法と言えます。仮に「自社のサービスのソースコードが肥大化してスパゲッティコードになってきている」ことを苦にしてマイクロサービス化を目指したとしても、組織構造がそのままなのであれば、それはマイクロサービスではなく分散モノリスとでも呼ぶべき代物になるかもしれません。

本気でマイクロサービス化によるアジリティの獲得を目指すのであれば、各チームに意思決定を委譲しなければなりません。しかし、組織構造や慣習など、さまざまな理由でそれが難しい企業の方が圧倒的に多数でしょうし、スタートアップについてはそもそも委譲できるほど人員がいないといった事が多く見られます。マイクロサービスの必要性について、私がお客さまに深い検討を促す理由はそこにあります。

組織が中〜小規模でありステークホルダーもそれほど多くない場合は、モノリシックなアプリケーションの方が明らかに開発効率が高いことに疑いを持つ方はいないと思います。技術的な面にフォーカスするならば、マイクロサービス化によってシステムが得られる利点を打ち消してしまう、もしくはそれ以上に新たな欠点が生じる可能性は大いにあるでしょう。私が「良くできたモノリスが最高」というメッセージをさまざまな場所で頻繁に発言しているのはこのような考えに基づいています。

「マイクロサービス化した場合に、将来的にシステムとして生じる難しさを組織として得られる利点を合算するとトータルでプラスになる」と判断できる場合のみ、マイクロサービスを検討すべきでしょう。だからこそ、「マイクロサービス」が単なるシステム分割を示す言葉として必要以上に用いられ、組織に対する検討が疎かになる風潮に対して疑問を抱いています。

 

マーケティングメッセージに踊らされてはいけない

テクノロジーの世界においては定期的に新技術が登場し、それらがトレンドを形成することがあります。テクノロジーを基軸としたサービスやプロダクトを提供する企業の多くは、その新技術に関連した自社製品をなるべく多くの方々に使ってもらうために、聞こえの良いマーケティングメッセージを発信します。現代で言えばマイクロサービスやコンテナなどはその好例でしょう。「世の中はマイクロサービスに向けて進んでいる」「マイクロサービスにはコンテナが必須」「マイクロサービスといえば Kubernetes」といった情報を耳にすることも多いかと思います。

技術情報へのアンテナが高い方ほど、これらの情報を盲信し、なるべく自分たちのプロダクトに取り入れようとしてしまうかもしれません。しかしそのスタンスでは、次々に登場するマーケティングメッセージに踊らされてしまい、適切な技術選定ができなくなってしまいます。私たちは有象無象の技術の中から、真に自社の課題を解決する技術を選定できるようにならなければいけません。

何か新しい技術やその概念と出会ったとき、公式ドキュメントを読んでみてください。そして、その技術が必要とされた理由、登場した経緯を理解し、実際に触ってみてください。かつてテクノロジーの世界では、新しい技術が登場しても膨大な料金を支払わなければ試せない時代がありました。何かのライブラリを試すためにライセンス費用が何百万円かかるとか、特定のサーバを使うために導入費用が何億円もかかるという時代があったのです。

ですが、現代はそうではありません。多くの優れたソフトウェアがオープンソースの形で提供され、その多くは驚くことに無料で試せます。AWS をはじめとしたクラウドコンピューティングの普及により、それらを動かす環境すらも非常に安価に手に入れ、PoC を行えるようになりました。触ってドキュメントを読むと、新しい技術やその概念が自分たちのシステム、ひいては自分たちのビジネスにどのような効果をもたらしてくれるのか、道筋が見えてくるはずです。

もちろん、ここで述べている 触る の中には、PoC を経た新しい技術を本番環境に試験的に導入してみる、ということも含まれています。運用をしなければ見えてこない課題もあるからです。導入してみて、自社にフィットしなければ切り戻すような判断もありえます。そうした技術的なトライ & エラーを許容できるような組織にしていくことは、最新技術を適切に活用できるか否かの観点において最も重要です。

 

課題から始めること、柔軟性ある文化を持つ組織を作ること

本来スタートアップ企業とは、強いビジョンや先進的なビジネスアイデアをもとにプロダクトを生み出し、高速に改善を続けていくことができる企業体であるかと思います。そうした企業体においては、ビジネスにおける目標の達成こそが最優先です。何かの技術を導入すること自体が目的化してはいけません。流行しているから、もしかしたら必要になるかもしれないから、といった安易な理由でシステムアーキテクチャの可能性を硬直化させるべきではないのです。

大切なのは、企業やサービスの課題をベースに意思決定すること。そして、自社を取り巻く状況の変化に合わせてシステムのアーキテクチャを柔軟に変えていけるような文化や組織体制を持つことです。柔軟さを持つ組織でさえあれば、1つや2つの技術選定ミスなどすぐに取り返しがつくものです。

自らの状況をふまえることなくコンテナ導入やマイクロサービス化を推進するのは、あまりにも無謀です。自分たちの課題の解決策としてさまざまな可能性を模索した結果、コンテナやマイクロサービスが正解だった、あるいは別の技術や考え方であった、という形こそ、本来あるべき状態だと筆者は考えます。かつてイギリスの自然科学者であるチャールズ・ダーウィンは「最も強い者が生き残るのではなく、最も賢い者が生き延びるのでもない。唯一生き残ることができるのは、変化できる者である」と述べました。これは企業においても同様です。どのような未来がやってきても柔軟に対応できるような組織であり続けることが、長きにわたり生き残り、成長していくための秘訣なのではないでしょうか。

そして、変化のしやすさは組織体制だけではなくアーキテクチャにおいても重要です。中長期にわたり改善し続けられるシステムであるためには「継続的な組み替えを前提とした、パーツの交換が容易なアーキテクチャ」である必要があります。たとえば、コンテナで解決すべき課題が出てきたからそこにはコンテナを使う、この部分は仮想マシンのほうが運用しやすいから仮想マシンに戻す、といったように、継続的な変更を柔軟に加えていけるシステムとそれを許容する組織でなければなりません。柔軟性を失ったシステムはやがて技術的負債と呼ばれるものになり、少しずつ自分たちの開発・運用を硬直化させていきます。そしてある日、ステークホルダーの1人が「フルスクラッチで再実装すればもっといいものになるはず」などと言い出してしまうのです。

最後に、AWS のソリューションアーキテクトへの相談をお勧めしたいと思います。彼らは、お客さまにとって適切なアーキテクチャを提案させていただくことが重要な業務の1つであり、技術選定のプロフェッショナルです。もしアーキテクチャ検討や技術選定において困りごとや悩みごとがあれば、ぜひ彼ら SA にご相談いただき、ベストな解を一緒に考えさせてください。
AWS のサービスやノウハウが、スタートアップ企業の技術選定と優れたアーキテクチャ構築になんかの形で貢献できれば幸いです。