-
これはアプリケーションアーキテクチャのひとつ
-
ひとことでいうと、アプリケーションを複数のサービスで疎結合に分離して扱う
- 別のサービスの変更に影響を受けたり与えたりをすることなく開発やデプロイが可能な状態
- データベースも分離され、各サービスは各サービスごとのデータベースを持つ
- コミュニケーションは決まったフォーマットを使う、HTTPとかRESTとかAMQPとか
- 最近ならgRPC? Android/iOS、Webフロントエンド等があるならJSON+Protobuf?がはやり?
- Introduction to gRPC | gRPC
- Protocol Buffers | Google Developers
- 全部JSONで自由にやるぜ!みたいなのはどうがんばっても崩壊してしまうので、何かしらの取り決めが作れるものを利用したほうがいいと思う
- 最近ならgRPC? Android/iOS、Webフロントエンド等があるならJSON+Protobuf?がはやり?
-
この記事ではECサイトを例に上げている
- アプリ用のAPI Gateway
- ショップとしてのフロントエンド
- アカウント管理とそのデータベース
- 在庫管理とそのデータベース
- 配送管理とそのデータベース
- 個々のサービスそれぞれを開発、運用していく
-
Microserviceのメリットは大きなアプリケーションでも個々の要素を小さく保つことでできるところ
- チームが1つ(か複数)のサービスに責任を持ってそれに集中できる
- 疎結合なので何かのサービスがダウンしても他のサービスは影響を受けない
- アプリケーション全体として、一部の機能が動かないけどそうではないものは提供ができる
- よく見る(?)やつ。こういうイメージ: https://www.githubstatus.com/
- アプリケーション全体として、一部の機能が動かないけどそうではないものは提供ができる
- 新しい機能(新しいサービス)を作るとき、利用する技術を選べる
- サービス間のコミュニケーション方法について取り決めがあれば、中身は何でもいいはず
- 例えば、あるサービスはGoで作られているけれど、別のあるサービスはJavaが使われている、みたいなもの
- データベースも個々のサービスが責任を持つので、どのサービスがどのデータベースを利用しているかは影響しない
- サービス間のコミュニケーション方法について取り決めがあれば、中身は何でもいいはず
-
逆にデメリットとして、分散システムになる、ということがある
- データまわり。一貫性とか分散トランザクションとか
- 記事ではSagaが使える、と書いてある
- サービスをまたいだテスト、開発をどのようにするか
- 基本的にはサービス内で完結するのがいいと思うのだけれども、アプリケーションはそうではないので、そこをどう解決するか…
- 例えば、開発環境だろうとも安定したものをかならず用意する(本番環境と同じように運用する)、で開発環境の安定性を取る、とか
- 例えば、複数のサービスにまたがる開発は Feature Flag の仕組みをいれて、実装は既にあるんだけど有効にはなっていない、とか
- このサイトで Feature Flag については書かれてなかったのでWikipedia: フィーチャートグル - Wikipedia
- 消費リソースの増加(マシンリソース、人的リソース)
- 💸💸💸💸💸
- データまわり。一貫性とか分散トランザクションとか
-
そしてこの記事では多くの問題に取り組む必要があると書いてある
- いつMicroservice architectureにするか
- 最初からやっても難しいしMonolithicで作って後から分割するのも難しい
- いつやるの!
今でしょ - Monolithicを読んだほうでも書いたけれど、アプリケーションの性質によっていつやるのがいいか、に万能な答えはないとおもう
- Monolithic だけれども、コード上での実装はそれぞれの役割が疎結合になっていると後からでも比較的分離しやすくてよいのではないだろうか
- データベースの操作を分離するのは難しいのでソースコードだけ分離されている、みたいなイメージ
- というか普通にそういう実装を意識したほうがきれいになるとおもう、ちょっと違う気がするけど Clean Architecture 的な
- 逆にMicroserviceだけれど密結合になってしまっているのであれば、分散システムになっただけのMonolithicで、双方のデメリットが強くでてしまうのではないだろうか
- 先にでていたECサイトの例に合わせて考えると、たとえばセッション管理の都合などでフロントエンドサービスがアカウント管理サービスと強く紐付いていて、アカウント管理サービスがダウンした場合にフロントエンドサービスもダウンしてしまう
- インデックスがまったく効かない大きなクエリがアカウント管理サービスのデータベースに実行される(CPUにクリティカルヒットするクエリ)などが起こる可能性は十分にある
- あるいはアカウント管理は頻繁に参照されるのでキャッシュをしているが、そのキャッシュがフルになってしまう、とか、キャッシュが空っぽになって一斉にクエリが走ってしまう、とか
- ダウンする可能性はいろいろな理由がありえそう
- 先にでていたECサイトの例に合わせて考えると、たとえばセッション管理の都合などでフロントエンドサービスがアカウント管理サービスと強く紐付いていて、アカウント管理サービスがダウンした場合にフロントエンドサービスもダウンしてしまう
- Monolithic だけれども、コード上での実装はそれぞれの役割が疎結合になっていると後からでも比較的分離しやすくてよいのではないだろうか
- どうやって個々のサービスに分割するか
- データの一貫性をどう担保するか
- “クエリ"をどう実装するか
- これは複数サービスにまたがるデータをどう取得するか、かな…?
- いつMicroservice architectureにするか
-
Related patterns とこの記事でたくさんのパターンが挙げられているけれど、これらはMicroserviceをやる上で遭遇する問題への対処法
- 対義語?的なものでは Monolithic <-> Microservice になる