マイクロサービスアーキテクチャとは?
ひとつのアプリケーションを複数のサービスに機能的に分割するためのアーキテクチャスタイル
(対義語:モノリシックアーキテクチャ、モノリス)
例、飲食店アプリケーション
モノリシックアーキテクチャ(モノリス)
・色々な業務を一つのアプリケーションが担っている
マイクロサービスアーキテクチャ
・業務ごとにアプリケーションが分かれていて、互いに連携している
・各サービスがDBをもっている
・クライアント側から必要なサービスのみ使用している
現代ではマイクロサービスアーキテクチャが主流になってきている。
【採用企業】
Amazon.com、NetFlix、LINE、クックパッド..
どうやってサービスを分割するか
定石:DDDのサブドメインごとにサービスを分ける
DDDのサブドメインとは?
https://codezine.jp/article/detail/9744
モノリシックアーキテクチャの問題点
1.アプリケーション理解の難易度が上がる
アプリケーションが大きくなりすぎることにより、一人の開発者がソースコードを完全に理解することができなくなる。バグを修正して新機能を正しく実装することが非常に難しく、時間のかかる作業になってしまう。
2.コミットから本番デプロイまでの道のりが長く険しい。CI/CDが難しい。
大規模アプリケーションは負荷が高く、ビルドにもテストにも時間がかかる。そのため継続的なデプロイが難しくなる。
3.スケーリングが難しい
リソース要件の矛盾が発生しやすい。例えばレストランデータは大規模なインメモリデータベースに格納されてるため、大量のメモリを搭載してるサーバーにデプロイしたいが、イメージ処理モジュールはcpuバウンドなので、cpuをいくつも搭載したサーバーにデプロイしたい。しかし、これらのモジュールは同じ一つのアプリケーションの一部なので、サーバーの構成で妥協を強いられる。
4.信頼性を担保することが難しい
サイズが大きすぎるためにアプリケーションの徹底的なテストが難しくなる。またすべてのモジュールが同じプロセス内で実行されているため障害の分離が出来ない。
5.次第に陳腐化していくテクノロジに縛られる
新しいテクノロジに乗り換えるコストが高くなる。
マイクロサービスアーキテクチャの利点
1.大規模で複雑なアプリケーションのCI/CDを可能にする
CI/CDで必要とされるテスト容易性を備えている
マイクロサービスアーキテクチャの個々のサービスは比較的小さいので、大規模システムより自動テストはずっと書きやすく、短時間で実行される。結果としてアプリケーションに含まれるバグは少なくなる。
CI/CDで必要とされるデプロイ容易性を備えている
個々のサービスは他のサービスから独立して、個別にデプロイできる。サービス内の変更をデプロイするからといって担当の開発者が他の開発者と調整する必要はない。自分の判断で変更をデプロイできるので、本番システムに頻繁に変更をデプロイすることがはるかに簡単になる。
開発チーム間の結合が疎になる
小さなチームの集合体というかたちで開発組織を構成できるようになる。各チームはほかのチームから独立して担当するサービスを開発、デプロイ、スケーリングできるので、開発ベロシティが大幅に上昇する。
CI/CDが実現できることで、サービスを市場に出すまでの時間が短縮され、顧客からの意見に素早く対応できるようになるし、信頼性の高いサービスを提供できるようにもなる。
2.個々のサービスが小さく、簡単にメンテナンスできる
サービスが比較的小さいので理解しやすいコードとなり、IDEが遅くなることもないし、アプリの起動も早くできる。
3.サービスを個別にスケーリングできる
各々のリソース要件にもっとも適したハードウェアにデプロイできる。
4.障害分離に優れている
あるサービスがメモリリークを起こしたとしても影響を受けるのはそのサービスだけ。その他のサービスは正常にリクエストを処理し続けられる。
5.新しいテクノロジを簡単に実験、採用できる。
新しいテクノロジを試して失敗しても、プロジェクト全体が頓挫するリスクを冒さずにその部分を捨ててしまうことが出来る。最初に選択したテクノロジによって、その後異なる言語やフレームワークを使えるかどうかに大きく制約されることがない。
マイクロサービスアーキテクチャの欠点
1.サービスの適切な分割方法を見つけるのが難しい
システムをサービスに分割するための具体的で明確に定義されたアルゴリズムはないので難しい。しかもシステムの分割方法を間違えると、一緒にデプロイしなければならない密結合のサービスから構成される分散モノリスができあがってしまう、、!(分散モノリスはモノリスとマイクロサービスアーキテクチャの欠点を併せ持つ)
2.分散システムは複雑になる
分散システムを作る分、当然考えることは増える。
サービス間のプロセス間通信や、複数のサービスにまたがるトランザクション(Sagaパターン)やクエリー(CQRSパターン)などを考えなければならない。
また複数のサービスが関わる自動テストを書くのも大変で、高度なデリバリースキルが求められる。
3.複数のサービスにまたがって使われる機能のデプロイには綿密な調整が必要になる
複数のサービスにまたがって使われる機能のデプロイでは関係するチームの間で綿密な調整が必要となる。
4.いつマイクロサービスアーキテクチャを採用すべきかの判断が難しい
開発初期のアプリケーションがまだ小さい段階では、マイクロサービスアーキテクチャが解決してくれる問題はそもそもないことがよくある。しかも凝った分散アーキテクチャを使うことにより開発作業はスローダウンする。(スタートアップ企業等は、ほぼ確実にモノリシックアプリケーションでスタートするべき)
しかしシステムが立ち上げられてからしばらくたって、複雑さへの対処方法が問題となったときにはアプリケーションを機能に基づいて一連のマイクロサービスに分割すべきである。
このタイミングが難しい。。
マイクロサービスアーキテクチャを実現するためのパターン
Sagaパターン
マイクロサービスでは各サービスが専用データベースを持っているが、従来の分散トランザクションは使えない。データ整合性の維持にSagaパターンと呼ばれるパターンを使う必要がある。
(まだ勉強中でよくわかってません)
ドメインモデルと集約(DDD)
複雑なビジネスロジックの実装にはDomain modelパターンをつかう。
しかし通常Domain modelパターンを使用するとドメインモデルが相互に絡み合ったクラスの織物になってしまうことが多いが、マイクロサービスアーキテクチャではサービス境界を越えるようなオブジェクトの参照を減らす必要がある。
そこでDDDの集約(Aggregate)パターンを使って対処する。
ドメインイベント
ドメインイベントとは、集約に起きた何かのことである。集約間、マイクロサービス間のやりとりはドメインイベントのやりとりによって行われる(変更イベントをpublishして、受け取る側がsubscribeする)
イベントソーシング
イベントをpublishするのを忘れてしまってもビジネスロジックは機能し続けてしまうので、バグの温床になりやすい。
そこでビジネスロジックの中心をイベントに据えるイベントソーシングを採用することにより、アグリゲートが作成、更新されたときは必ずイベントがパブリッシュされていることを保証させる。
CQRS
マイクロサービスでは各サービスに専用のデータベースを構えているのでクエリが難しくなる。
そこでCQRSパターンをつかって対処する。
https://qiita.com/shuma_horii/private/fd800ba69a930158446e
その他マイクロサービス特有のAPI設計のやり方や、デプロイの方法、テストの開発方法等いろいろ勉強することが多そう。。
参考文献