MSAに入門してみる

MSAって何?🤔
MSA(Micro Service Architecture)とは単一のアプリケーションを一連の小さなサービスとして開発する手法のこと。
つまり?
大きなサービスを一つ作って運用していくのではなくて、小さなサービス群を用いて運用していくこと。
何が嬉しいの?
提唱したJames LewisとMartin Fowlerによると以下のようなメリットがあるらしい。
MSAの特徴について🚀
サービスのコンポーネント化
コンポーネントとは、独立して交換およびアップグレード可能なソフトウェアのユニットです
各サービスをコンポーネント化することによって使い回しがしやすくなる。
例えば、デプロイを各サービスで回すことができるようになるため、効率よくサービス開発ができる。
それに加えて、サービスを利用する際に使用されるrpcなどの軽量なメッセージングサービスを使用することによってインターフェイスが確立されるので不用意な変更が起こりにくい。
デメリット
インメモリの呼び出しよりもコストが高くなってしまうため、APIの粒度に気をつける必要がある
ビジネス能力を中心に組織化
大規模なモノレポアプリケーションの多くの場合、チームは以下のように分かれる。
- UIチーム
- デザイナーチーム
- バックエンドチーム
- インフラチーム
- etc...
このようにレイヤーごとに分けてしまうと小さな変更であったとしても多くのチームと連携して機能を構成する必要があり、平たくいうと腰が重くなってしまう😭
各サービスにおいてfeatureチームとして独立することによってより開発効率を向上させることが可能になる。
プロジェクトではなく製品(Product not Project)
開発チームが本番環境のソフトウェアに対して全責任を負うという Amazon の「あなたが構築し、あなたが実行する」という考え方です。
多分この言葉に集約されている。
従来なら開発チームはとりあえず動くものを作成して、完了したら保守・運用チームにその後の責任を押し付けて自分達は新たなるサービスの構築に取り掛かる。
MSAではそれを真っ向から否定している。
スマートエンドポイントとダムパイプ
この辺から何言ってるのかわからん()
ダムって?
メッセージルーターとしてのみ機能するという意味らしい。
マイクロサービスは可能な限り分離され凝縮度を上げることを目指す。
- リクエストを受信
- 適切なロジック
- 応答を生成する
BPELやWS-ChoreographyではなくてシンプルなREST風プロトコルを使用する。
デメリット
ただ、各サービスの通信については考えなければならない。
粒度の低い通信が横行していてはおしゃべりな通信になってしまう。
きめ細かい通信から荒いアプローチに変えていく必要がある。
分散型ガバナンス
中央管理(モノレポ)だと単一のテクノロジーに標準化してしまう。
マイクロサービスだとサービスが分割されているので、好きにテクノロジーを選ぶことができる(何でも好きにやればいいってもんでもないが)
分散型データ管理
「ポリグロット パーシスタンス」
→サービスを分割するだけでなく、データベースもサービスの分だけ分割する。
マイクロサービス間でデータの責任を分散することは、更新の管理に影響を及ぼしてしまう。
トランザクションをはると一貫性は担保されるが、時間的な結合が著しくなってしまい、複数のサービス間で問題が生じてしまう。
よくわからなかったのでGPT君
ユーザーが商品を注文する際、以下のステップが必要です:
- 注文システムで注文を作成
在庫システムで在庫数を減らす
これらの操作を1つのトランザクションで行おうとすると:
両方のシステムが同時に利用可能である必要があります。
一方のシステムが遅延したり、ダウンしたりすると、全体の処理が失敗します。
トランザクションが長く続くと、他の操作がブロックされる可能性があります。
これが「時間的な結合」と「複数のサービス間での問題」です。
代替アプローチとして、最終的な一貫性を採用する場合: - 注文システムで注文を作成
在庫システムに非同期メッセージを送信して在庫を更新
この方法では、一時的に在庫数と注文数に不整合が生じる可能性がありますが、システムの柔軟性と耐障害性が向上します。
このトレードオフは、ビジネスの要件や許容できるリスクレベルに応じて選択されます。多くの場合、短期的な不整合よりも、システムの可用性と応答性の方が重要とされます。
インフラの自動化
クラウドが普及してきていることも相まってマイクロサービスの構築・展開・運用の複雑さが軽減された。
ソフトウェアが実際に動くかどうかをチェックする必要があるため、CIを回して自動テストを行う。
その際にマイクロサービスの場合だと軽量にCIを回すことができるし、先述したCDも軽量に行うことができる。
失敗を考慮した設計
サービスをコンポーネントとして設計すると、アプリケーションはサービスの障害に耐えられるように設計する必要がある。ただ、モノレポと比較すると複雑性を増してしまう。
その結果、MSAのチームはUXに対してどのような影響があるのかを徹底的に考慮する必要がある。
サービスはいつでも失敗する可能性があるため、失敗を迅速に計測して自動的に復旧できるのが理想的。
参考

MSAでの一貫性の仕組み
相手のサービスのデータソースに直接アクセスできない。
- トランザクションによる一貫性が利用できない
- 自サービスと相手サービスそれぞれの結果整合性によって全体の一貫性を保つ。
代表的な仕組み
segaパターン
補償トランザクションによる(事後)結果整合性
- 処理の成功を前提とした楽観的な呼び出し方法
- 一部の処理が失敗した際にすでに完了した処理を取り消す「補償トランザクション」によって生合成を担保する。
TCC(Try/Confirm/Cancel)パターン
予約ベースの(事前)結果整合性
- 処理完了の可否を事前に確認した上で処理を実施する
- Tryフェーズにより不整合の生じる処理を行わないことで整合性を担保
参考