マイクロサービスとは ― モノリスとの違いと分け方
マイクロ
マイクロサービスとは、小さなサービスを組み合わせて1つのアプリを作る方式
すべての機能を1つのプログラムにまとめたアプリでは、小さな修正でも全体を作り直して入れ替えます。マイクロサービスとは、1つのアプリを小さなサービスの集まりとして作る方式で、変えたサービスだけを入れ替えられます。機能ごとに分かれたサービスは、それぞれ別のプロセス(実行中のプログラム)として動き、HTTPのAPIなどの軽い仕組みで呼び合います。
以下の説明は、James LewisとMartin Fowlerが2014年に書いた記事「Microservices」に基づいています。2人は、正式な定義は無いと断ったうえで、多くのマイクロサービスに共通する特徴を挙げています。各サービスは業務の機能ごとに作られ、ほかのサービスと関係なくデプロイできます。
モノリスとマイクロサービスの違いは、作り直しと増やす単位
モノリスとは、すべての機能を1つのプログラムにまとめて作るアプリです。Fowler・Lewisは、リクエストを受けて業務の処理をし、データベースを読み書きして画面を返すサーバ側のアプリを例に挙げています。この処理を1つのプロセスで行うのが、モノリスです。
作ったプログラムを本番のサーバに置いて動かすことを、デプロイと呼びます。モノリスでは、小さな部分を変えるだけでも、アプリ全体を作り直してデプロイします。マイクロサービスでは、変えたサービスだけをデプロイし直します。
次の図は、商品一覧・注文・配送の3つの機能を持つ通販サイトの例です。出来事を選ぶと、作り直す範囲・増やす部分・止まる範囲が、2つの方式で切り替わります。
- 商品一覧変えていないが
作り直す - 注文変えていないが
作り直す - 配送直した
部分
- 商品一覧2台そのまま・
変更なし - 注文2台そのまま・
変更なし - 配送2台を入れ替え作り直して
デプロイ・直した 部分
- 商品一覧一緒に
増える - 注文負荷が
増えた 部分 - 配送一緒に
増える
- 商品一覧2台のままそのまま・
増やさない - 注文2台 → 10台台数を
増やす・負荷が 増えた 部分 - 配送2台のままそのまま・
増やさない
- 商品一覧同じ
プロセスなので 止まる - 注文同じ
プロセスなので 止まる - 配送不具合の
起きた 部分
- 商品一覧動くそのまま・
見られる - 注文動くそのまま・
受け付ける - 配送止まる止まる・不具合の
起きた 部分
NISTの文書SP 800-204も、通販サイトを例に同じ違いを挙げています。たとえば、請求の機能を直すときは、マイクロサービスなら請求のサービスだけを作り直せば済みます。違いをまとめると、次の表になります。
| 比べる | モノリス | マイクロサービス |
|---|---|---|
| デプロイの | アプリ全体 | 変えた |
| 台数を | アプリ全体 | 負荷の |
| 1つの | プロセスが | ほかの |
| データの | 1つの | サービスごとに |
| 機能どうしの | 同じ | ネットワーク越しの |
モノリスでも、同じアプリを何台も並べてロードバランサで振り分ければ、台数を増やせます。違いは、台数を増やす単位がアプリ全体になる点です。そのため、負荷が増えていない機能の分までサーバの資源を割り当てることになります。
サービスの分け方は、業務の機能を単位にする
業務の機能で分ける
Fowler・Lewisは、技術の層ではなく、業務の機能を単位にサービスを分けると説明しています。画面・業務の処理・データベースでチームを分けると、小さな変更でも複数のチームの調整が要るためです。業務の機能で分けたサービスは、その機能の画面からデータの保存までを、1つのチームが受け持ちます。
サービスの大きさは、事例によって幅があります。Fowler・Lewisが聞いた例では、大きいものでも、1つのチームが12人までで受け持てる大きさでした。
サービスごとにデータを持つ
モノリスでは、1つのデータベースを全体で使うことがよくあります。マイクロサービスでは、サービスごとに自分のデータベースを持たせる作りが好まれます。同じ種類のデータベースを別々に持つことも、サービスごとに違う種類を選ぶこともあります。
できるだけ状態を持たない
前のリクエストの内容をサービスの中に覚えておかない作りを、ステートレスと呼びます。NISTは、サービスはいつ止まっても回復できるよう、できるだけステートレスにすると書いています。覚えておく必要のある情報は、データベースやキャッシュなどの、信頼できる別のサービスに置きます。
一緒に変わるものはまとめる
Fowler・Lewisは、同じ時期に変わるものは同じところに置くと書いています。2つのサービスをいつも一緒に変えているなら、その2つはまとめたほうがよいというサインです。
マイクロサービスのメリット
NISTの文書とFowler・Lewisが挙げる主なメリットは、次のとおりです。
- 変えたサービスだけをデプロイできるため、更新を早く出しやすい
- 負荷の高いサービスだけを選んで、台数を増やせる
- サービスどうしの結び付きを弱くすれば、1つのサービスの障害がほかに広がりにくい
- サービスごとに、プログラミング言語やデータベースを選べる
- サービスごとにチームを分け、チームごとに開発を進められる
NISTは、サービスのAPIの形を変えなければ、中身の作りを変えてもアプリ全体の動きに影響しないことも挙げています。変えたサービスを止めずに本番へ出す方法は、ブルーグリーンデプロイとカナリアリリースの記事を読むと分かります。
マイクロサービスのデメリット
分散による複雑さ
サービスどうしの呼び出しはネットワークを通るため、同じプロセスの中の呼び出しより時間がかかります。相手のサービスが止まっていて、応答が返らないこともあります。呼び出す側はこの失敗に備える必要があり、その分だけ複雑になります。Fowler・Lewisは、この点をモノリスに比べた欠点としています。
失敗が続く相手への呼び出しを、いったん止める仕組みもあります。NISTはこの仕組みをサーキットブレーカと呼び、障害が次々に広がるのを防ぐと説明しています。
データの一貫性
1つのデータベースを使うモノリスでは、複数のデータの更新を1つのトランザクションで行えます。サービスごとにデータを分けると、複数のサービスにまたがる更新を1つのトランザクションにまとめるのは難しくなります。複数の場所にまたがるトランザクションを、分散トランザクションと呼びます。その方法の1つが、分散データベースの記事で説明している2相コミットです。
Fowler・Lewisは、分散トランザクションは実装が難しいと書いています。そのためマイクロサービスでは、時間がたてばデータがそろう状態で良しとすることが多くなります。これは、NoSQLでいう結果整合性です。食い違いが起きたら、後から打ち消す処理で直します。
運用の負担
NISTは運用の負担として、1つのアプリではなく、多数のサービスを監視する必要があることを挙げています。各サービスの状態と全体の状態をまとめて見る仕組みも要ります。Fowler・Lewisも、サービスが多い構成のデプロイは1つのモノリスより難しく、道具への投資は欠かせないと書いています。複数のサービスをまたぐリクエストの遅さを調べる方法は、オブザーバビリティの記事で説明しています。
- すべてのサービスを動かして通信させる環境が要るため、結合テストが難しい
- 利用者によって新しい版と前の版のサービスを呼び分ける、版の管理が要ることがある
- サービスどうしの呼び出しがAPIになるため、APIごとに認証などの安全対策が要る
モノリスとマイクロサービスのどちらを選ぶか
NISTは、マイクロサービスが使われる理由として、多くの端末からの利用と、利用者の増加に合わせた拡張を挙げています。組織や市場の変化に合わせて、頻繁に更新したいことも理由の1つです。
一方で、AWSのホワイトペーパーは、モノリスなど別の方式が向く場合もあるとしています。規模・複雑さ・用途を見て、場合ごとに決めるという立場です。Fowler・Lewisも、マイクロサービスが今後の方向だと確信はしていないと書いています。
サービスの境界を正しく引くのは難しい作業です。境界をまたいでコードを動かすのも、1つのプロセスの中で動かすより大変です。Fowler・Lewisは、最初はモノリスで作り、問題になってから分けるという意見を紹介しています。ただし、プロセスの中でうまく働く取り決めが、そのままサービスの取り決めに向くとは限らないとも書いています。
既存のモノリスをクラウドへ移すときに機能ごとに分け直すやり方は、クラウド移行の記事で説明しています。
マイクロサービスを支える仕組み
NISTによると、各サービスはアプリケーションサーバの中のプロセス・仮想マシン・コンテナのどれでも動かせます。NISTは、マイクロサービスのアプリが、コンテナを使ったクラウド向けのアプリとみなされることが多いとも書いています。AWSのホワイトペーパーは、コンテナで作る構成と、サーバーレスで作る構成の両方を紹介しています。コンテナの配置を受け持つサービスとしては、Amazon ECSとAmazon EKSを挙げています。2つの違いはECSの記事で比べています。サービスごとにコンテナの数を保ち、変わらない接続先を与える仕組みは、Kubernetesの記事で説明しています。
- APIゲートウェイは、利用者からのリクエストの入口を1つにまとめ、正しいサービスに振り分けます。AWSでは、Amazon API Gatewayがこの役を受け持ちます
- 同じサービスを複数台並べたときは、ロードバランサが負荷を均等に分けます
- サービスどうしを待たせずにつなぐときは、メッセージキューを間に置きます
- 複数のサービスを決まった順に呼ぶ流れは、AWSではStep Functionsで管理できます
- サービスが公開するAPIには、REST APIがよく使われます
- サービスの数だけ環境を作るため、構築とデプロイを自動化します。環境をコードから作る方法をIaCと呼びます
NISTは、APIゲートウェイのもう1つの使い方も挙げています。モノリスの一部を少しずつサービスに置き換えて移行するとき、利用者から見た接続先を変えずに済むよう、前面に置く使い方です。
マイクロサービスとSOAの違い
SOAは、システムの機能をサービスとして作り、組み合わせて使う考え方です。日本語ではサービス指向アーキテクチャと呼びます。NISTは、2つに共通する点を3つ挙げています。機能をサービスとして提供すること、サービスどうしが呼び合えること、サービスどうしの結び付きが弱いこと(疎結合)です。
2つの関係の見方は、資料によって分かれます。NISTは、別の方式とする見方、SOAの型の1つとする見方、SOAを洗練させたものとする見方の3つを紹介しています。最も多い意見は、違いは方式そのものではなく、開発やデプロイの進め方と使う技術にあるというものです。
Fowler・Lewisは、SOAという語の意味が人によって大きく違うと書いています。2人が見たSOAの多くは、ESBと呼ぶ製品でモノリスどうしをつなぐものでした。ESBは、サービスの間に置いて、メッセージの振り分けや変換を受け持つ仕組みです。
Fowler・Lewisによると、マイクロサービスでは、通信の経路に複雑な処理を入れず、処理をサービスの側に置く作りが好まれます。マイクロサービスをSOAと呼ぶことを拒む人もいれば、SOAの一形態と考える人もいると書いています。
参考にした資料
- James Lewis・Martin Fowler「Microservices」(2014年3月25日)
- NIST Special Publication 800-204「Security Strategies for Microservices-based Application Systems」(2 Technology Background、Appendix A)
- AWS Whitepaper「Implementing Microservices on AWS」
練習問題(全5問)
正解:
マイクロサービスは、
正解:配送の
マイクロサービスでは、
正解:注文の
マイクロサービスは、
正解:サービスどうしの
サービスどうしの
正解:複数の
Fowler・Lewisは、
選んでから「採点する」を押すと、解説つきで答え合わせができます。