こんにちは。 株式会社ラクスで先行技術検証をしたり、ビジネス部門向けに技術情報を提供する取り組みを行っている「技術推進課」という部署に所属している鈴木(@moomooya)です。
ラクスでは有り難いことにサービスが順調に成長しています。今後の成長に対応できるようにするために、継続的な検討課題としてより拡大可能なアーキテクチャの検討を行っています。
拡大成長可能なウェブアプリケーション(のバックエンド)アーキテクチャとしてすぐに挙がるのが「マイクロサービスアーキテクチャ」だと思いますが、マイクロサービスアーキテクチャが一般的に議論されるようになったのが2015年頃からだったと思います。それ以来いろいろと考え続け、従来のモノリシックアーキテクチャ群との間にあるアーキテクチャとイメージがつながってきたのでまとめてみたいと思います。
この記事でそれぞれのバックエンドアーキテクチャを俯瞰的に比較することで、ウェブアプリケーション開発時のヒントになると思います。
各アーキテクチャについて
今回比較する各アーキテクチャはどれもウェブアプリケーションのバックエンドアーキテクチャになります。
昔ながらのモノリシックアーキテクチャが無秩序でつぎはぎだらけなメンテナンスしにくいソースコードに陥りやすいという課題感は 1997 年に発表され、 1999 年に Big Ball of Mudという論文で広く認知されるようになりました(参考:大きな泥だんご - Wikipedia)。
それから15年後の 2014 年に ThoughtWorks 社の James Lewis 氏と Martin Fowler 氏が自社ブログにて『マイクロサービス』を発表しました。
誤解を恐れず言うのであれば発表された「マイクロサービス」の定義内容はコンセプチュアルな内容、言い換えるのであれば「実用可能ではあるが想定が極端なアーキテクチャコンセプト」であったと思います。
2014年に発表されてからの数年間、ITアーキテクトの皆さんはどうやったらプロダクトコードに落とし込むことができるのか理解と解釈を進めたと思います。 そのうち、マイクロサービスアーキテクチャで想定されてる規模とマッチするウェブアプリケーションに対してはマイクロサービスが適用され始めましたが、マッチするウェブアプリケーションの範囲はITアーキテクトたちが考えていたほど広くはありませんでした。
とはいえマイクロサービスアーキテクチャのコンセプトは長年求められているものでした。なんとかそのコンセプトを適用することができないかと模索した結果、現実的なアプローチとして 2017 年に Cloud Elements 社の Ross Garrett 氏が自社ブログにて『ミニサービス:実用的なマイクロサービスアーキテクチャ』という投稿を公開しています(詳細は更にリンクされているTechTargetの記事)。 これはマイクロサービスアーキテクチャほど細かく分割はせずに、利用する技術要素も既存技術でまかなう考え方で、モノリシックアーキテクチャとマイクロサービスアーキテクチャの間にある落とし所を探すアーキテクチャの一つとなりました。
といっても、ミニサービスアーキテクチャも複数サービスを開発・運用していくという部分では変わりなく、それよりも更に小規模であったり動的なスケールが必要ないウェブアプリケーションにとっては導入によるデメリットが大きく、積極的に適用出来るわけではありませんでした。 モノリシックアーキテクチャとミニサービスアーキテクチャの間に位置づけられるアーキテクチャとして、2018 年に Root Insurance 社の Dan Manges 氏が自身のブログで『Railsのアーキテクチャ:モジュラーモノリス』としてモジュラーモノリスアーキテクチャを発表しました。 これはモノリシックアーキテクチャをベースに、サービスに分割するのではなくモジュール(Railsなのでgem)に分割していき、最終的には単一のウェブアプリケーションとしてデプロイするアーキテクチャでした。
ここまでをまとめるとアーキテクチャが生まれた順序は以下のようになります。
各アーキテクチャ間の関係は以下のようになります。
それぞれのアーキテクチャについてもう少し詳細に見ていきたいと思います。
モノリシックアーキテクチャ
デプロイメントラインが1つで、バックエンドサービスが1つのアーキテクチャ。
デプロイメントラインが1つであることは利点で『マイクロサービス』でも立ち上げ時などの速度を重視するタイミングではモノリシックで構築することが推奨されています。
反面、アップデートを重ね規模が大きくなると開発コストが増大するとされていますし、感覚値としてもその通りであるという印象があります。
特に成功したサービスほど急速にアップデートが行われることを考えると、成功した場合にはどこかでリアーキテクトを考える必要があると言えます。ただ……開発エンジニアの想定(というか渇望)よりはモノリシックのままで対応できる範囲は広く、それが判断を難しくしている原因とも思います。
マイクロサービスアーキテクチャ
2014年に提唱されて以来、ノウハウがまとまった書籍が揃ってきました。
まずはサム・ニューマン著『マイクロサービスアーキテクチャ』を読みましょう。
概要についてはこの本で網羅的に抑えることが出来ます。ちなみに原著の方では第2版がO'reilly Learning Centerで先行リリースされています "Building Microservices, 2nd Edition"。
※追記:2022/12/2に第2版の翻訳版が発刊されました
「マイクロサービスアーキテクチャ」の流行もやや落ち着き、冷静な議論が出来るタイミングが来ていると感じていますが、忘れてはいけないのは提唱者ら自らが「『マイクロサービスアーキテクチャから始めるべきではない』というのは合理的な議論である。モノリスから始めて、モジュール構造を保って、モノリスであることに問題が生じたらマイクロサービスに分割する」と語っていることを忘れてはいけません。
One reasonable argument we've heard is that you shouldn't start with a microservices architecture. Instead begin with a monolith, keep it modular, and split it into microservices once the monolith becomes a problem.
モノリスからマイクロサービスへの移行パターンについても翻訳本はまだ出ていませんが、"Building Microservices"と同じ著者で"Monolith to Microservies"という本が2019年に出版されています。
と、思ったら2020年12月26日に翻訳本が発刊されるようです! うれしい!!
ミニサービスアーキテクチャ
マイクロサービスアーキテクチャは破壊的すぎるとしてミニサービスアーキテクチャが提唱されています。大きな違いとしては以下があります。
- サービス分割単位は機能単位ではなくドメイン単位
- データストアは必ずしもサービスごとではなく、共有データストアでもOK
- サービス間通信はpub/subではなく、httpでもOK
調査会社のガートナー社では以下のように図解しています。
また私が以前にMicroservices Meetupで発表した資料へのリンクも置いておきます。
モジュラーモノリス
マイクロサービス、ミニサービス、とサービスを分割――すなわちデプロイメントラインを複数にする――というアプローチを前提においていましたが、デプロイメントラインが複数になるということは 複数のWebサービスを開発・運用する ということになります。このコストは無視できません(なんせより大きな成功につながるかもしれない別のWebサービスを展開するのと同等のコストです)。
この問題について1つのデプロイメントラインを維持しつつ、サービス分割をモジュール分割とすることで解決しようとしたアプローチがモジュラーモノリスになります。
2019年にShopifyが実際に移行した取り組みで話題になりました。Shopifyでは分割後のモジュールとの依存を管理するために Wedge というツールを開発してプロジェクトを進めていたようです(このツールもOSSとして公開したいとのこと)。
(2021.1.6追記)WedgeはPackwerkとして公開済みとコメントにて教えていただきました。 takahashimさん、ありがとうございます。
翻訳記事も見つけました。
モジュラーモノリスにおいてデータストアはどのように扱うのか、という点においてはミニサービスアキテクチャのように共有データストアを利用するケースもあれば、モジュール単位でデータストアを持つ方法も試されているようです。このあたりの話はMnolith to Microservices(モノリスからマイクロサービスへ)の第1章「必要十分なマイクロサービス」の「モノリスの課題」や、第4章「データベースを分割する」が参考になると思います。
モジュラーモノリスについては弊社の先行技術検証の取り組みである「技術推進プロジェクト」の成果として別途記事にもしているのでご参照ください。
各アーキテクチャの使い分け
マイクロサービスに必要なもの
これまでそれなりの時間をかけて検証を重ねてきましたが、マイクロサービスアーキテクチャを採用するのは相当にハードルが高いと感じました。
最初に必要となる適切に構成されたコンポーネント群についてはサービス分割を念頭に起きながらサービスの開発・運用を一定期間続けることできれば、ドメイン知識の蓄積によりなんとか「適切な構成」を見出すことは出来るかもしれません(「サービス分割を念頭におく」ことが相当に難しいことはともかく)。
スキルレベルの高いエンジニアチーム、具体的には分散システムの開発・運用を実現するためのツール群や設計思想などに精通したエンジニアチームとなりますが、これも一朝一夕では厳しくとも時間をかければなんとか実現出来ると思います。
ただ、それらを揃える労力を「マイクロサービスアーキテクチャ」を実現するコストとして投入するかというと悩ましいところです。
BtoB, BtoCの観点から
ラクスはBtoBでのビジネス展開をしているわけですが、BtoBサービスにおいてはマイクロサービスアーキテクチャの必要性はそこまで高くないと判断しています。
マイクロサービスアーキテクチャの旨味である「オートスケールと組み合わせての予想しない負荷への自動対応」だとか「日に何十回もの小刻みな本番環境へのリリース」といったBtoCで求められることは特定多数がユーザーであるBtoBではあまり求められていないです1。
とはいえサービスが大きくなったときにモノリシックアーキテクチャのままであることにもつらさがあるため、モノリスとマイクロサービスの間のどこかを目指すことになると考えています。
直近ではモノリスの状態で、問題が出始めたら"Monolith to Microservices"でも「多くの組織にとって、モジュラーモノリスは優れた選択肢である」と書かれているようにモジュラーモノリスを目指していくことになるのではないかと考えています。
コンテナオーケストレーションだとか、分散ロギングなどの運用ノウハウが十分に貯まったころに、次いでミニサービスアーキテクチャが選択肢に入ってくるとイメージしています。
まとめ
さて、この数年間で比較されてきた
の4つを俯瞰して見渡してみました。アーキテクチャ検討の参考になればと思います。
なお、現時点では2先述の通り「モジュラーモノリス」が一番現実解に近いかな……と検証を行っていますが、モノリシックアーキテクチャに比べるとモジュールとして分離するコストが上乗せされる分高くなります。どの程度の規模で分離しはじめるべきなのか、見極めラインは今後も探っていきたいと思います。
追記
[2020.12.21追記] 今年翻訳本が発刊されたクリス・リチャードソン著『マイクロサービスパターン』もおすすめです。サービス分割に関する部分など、マイクロサービスに限らずミニサービスやモジュラーモノリスにも役に立つ内容が掲載されています。ちなみに元ネタはこの本の著者が運営するウェブサイト Microservices.io です。
[2021.1.6追記] コメントにて takahashim さんから「WedgeはPackwerkとして公開済み」と教えていただきました。2020年9月に公開されていたようです。名前が変わっているとは盲点でした。
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com