Microservice
の粒度について以下の記事から学んだことを、知識整理のために投稿。
Microservices antipatterns and pitfalls
Microserviceはどれくらいの大きさか
-
Microservice
アーキテクチャにおいてサービスの粒度は非常に大切。 - その粒度はプロダクトの性能、変更容易性、安定度など様々な面に大きく影響してくる。
- ではどれほどの粒度で
Microservice
を作れば良いのだろうか。
Microservice
における1サービスとは
- 開発者たちは、よくサービスをjavaで言う所の
class
と混同して考えがち。 -
Microservice
におけるサービスは単一の責任を持ち、明確で簡潔な役割を持つシステム全体のうちの1コンポーネント。別にclass
の数は関係ない。 -
class
の数がサービスの粒度ではないとしたら、何が粒度を決定するのか
サービスの粒度が正しいかを検証する3つの分析
1.Service Scope and Function
- そのサービスは何をするのか。文字に書き起こしてみるのが最良の方法。あれもこれもと色々とサービスの担っている仕事が書けるようであれば、そのサービスは役割を持ちすぎている。
- サービスの
凝集
を考えることはサービスの担う機能や役割を分析するのに、非常に大切。
以下の機能をMicroservice
で構築するとするといくつのサービスに分割できるか。
- ユーザ情報登録
- ユーザ情報更新
- ユーザ情報取得
- ユーザ情報の通知
- ユーザのコメント登録
- ユーザのコメント取得
上の3つはユーザ情報の単純なCRUD
。
下の2つもユーザのコメントの単純なCRUD
。
真ん中の1つは上で記載した2つのグループには属していない。
つまり、この機能群は3つのサービスに分離できる。
サービスについての理解度が上がっていけば、機能はより正確に小さく分離することができるようになっていく。
2.Database Transactions
- データベースのトランザクションは
ACID
な操作になっていなければならない。データベースの更新はunit of work
を実現でき、トランザクション中に何かエラーが起きれば適切にロールバックできる必要がある。 -
Microservice
アーキテクチャにおいてはサービスはアプリケーションとして物理的に分離されている。複数のアプリケーションで単一のトランザクションを実現するのは非常に難しい。 -
Microservice
アーキテクチャは一般的にBASE
なシステムとして構築する。それぞれのサービスが単一のアプリとして動くわけだから、Consistent
ではなくEventually Consistent
しか保証できないのは当然な気がする。 - 分割したサービスが複数のサービスのデータベースにまたがってトランザクションを保持しなければ
Eventually Consistent
を担保できないならば、サービスの粒度を大きくすることを検討すると良いだろう。
※この記事がACID
,BASE
について端的に記述されていてわかりやすかった。
3.Service Choreograohy
- サービス全体の構成の話だと思う。
- サービス間の連携について考える必要がある。前提として、あるサービスがあるサービスを呼び出すとき、システム全体のレイテンシは下がるということ。
HTTP
プロトコルで5つのサービスがシーケンシャルにイベント処理を行ったとして、サービス間のイベント発行に100ms
かかるとしたら、システム全体で0.5
秒かかってしまう。 - 一つの業務リクエストで5,6個のサービスが処理を行うような構成になっているとしたら、サービスの粒度をもう少し大きくした方が良い。そうすることで、システム全体の信頼性・安定度・パフォーマンスは向上する。
- しかし同時に大量のリクエストがシステム内に流れ込んでくる場合はサービスの粒度を大きくすると、レスポンシビリティは下がってしまう。そこで、リアクティブアーキテクチャと融合したアーキテクチャにするという選択をすることで、レスポンシビリティを損なわない構成にすることもできる。
- 重要なことはシステム全体の信頼性とレスポンシビリティはトレードオフになっているということ。
Microservice
の粒度の落とし穴にはまらないためには
アーキテクチャにおける全ての決定はトレードオフになっているということ
-
Service Choreography
でも記載したが、一つの業務リクエストを複数のサービスで処理をしなければいけない構成のパフォーマンスの問題を解決するために、複数の十分に小さいサービスを集めて一つのサービスに固めることでパフォーマンスの問題は解決できるかもしれないが、リリースしやすさ・テストのしやすさを犠牲にしてしまう。 - 上の例のようにアーキテクチャにおける全ての決定にはトレードオフが発生するということを開発者・アーキテクトは理解しておくべきだ。
- このトレードオフは何を基準にどちらを取ると判断するべきなんだろうか。
トレードオフの取捨選択
開発者・アーキテクトはMicroservice
アーキテクチャを採用する場合に以下の3つの質問に答えられるようになっているべき。
-
Microservice
で何をするのか - 達成したい最も重要なビジネス要求は何か
- アーキテクチャ特性のうち最も重要視するものは何か。
これらが答えられていれば、自ずと自分たちがMicroservices
に求めるものがなんなのか、わかってくる。そしてトレードオフの発生する決定は、Microservice
に求めるものに合わせて行っていけばいい。
Microservice
の粒度について思ったこと
結論、Microservice
の粒度を決定するのはMicroservice
アーキテクチャに移行するアプリケーションを考えるにあたって、非常に重要で難しいことだと思う。
そしてどういう粒度でMicroservice
に切り分けると決定しても、完璧な粒度の設計は不可能だと感じる。
自分達に必要なものが何で、それを達成するためにどうしてMicroservice
に移行したいのか。
これを軸にしてMicroservice
アーキテクチャの設計を行うことを忘れてはならないと思った。(まあ、Microservice
に限った話ではないかw)
記事の中ではMicroservice
アーキテクチャは、現在紛う事なく産業の主流になっていると述べており、全てのエンジニアはこの流れに乗るべきだそうだ。
Microservice
に特化したフレームワークも多く作られている世の中なので、実際に今度は物を作ってみようと思う。