この記事は ZOZO #3 Advent Calendar 2021 17日目の記事になります。
現在携わっているプロジェクトでは、少しだけモジュラーモノリスに挑戦してみました。マイクロサービスとどこが違うのか少しだけ整理してみようかと思います。
簡単なアーキテクチャは↑のような感じ。
コンテキスト間の連携についてはマイクロサービスであればgRPCやREST API、メッセージングなどを使用しますが、モジュラーモノリスであれば、コンテキスト間にモノリスアダプタをおいて、このアダプターを経由してやりとりします。
ポイントとしては
・ トランザクションの境界は各コンテキスト。モノリスであっても2相コミットはしないこと
・ モノリスであってもコンテキスト間ではモデルを共有しないこと。(今回はprotocol bufferを使用)
・ モノリスアダプタの実装はできるだけgRPCに近い実装になるようにした
これを実装してみての感想を2つ。
1つ目はモノリスアダプタの実装は頑張る必要なかったかも。色々こねくりまわしてgRPCぽい実装にするよりもモノリスの利点を生かして単純なメソッド呼び出しで十分だったかと。
もう一つが重要で、、、結局マイクロサービスで実装するのと変わらない大変さがあること。
特にトランザクションの境界。結局コンテキストごとにわかれるので、上記図、コンテキスト1からコンテキスト2への連携で考えるとコンテキスト2のトランザクションが成功し、その後、コンテキスト1が失敗すれば、コンテキスト2を元に戻す処理を実行する必要があります。
マイクロサービスでいう、補償トランザクションですが、モジュラーモノリスにしたところで必要になるのです。
であれば、マイクロサービスでいうオーケストレーションツールに近いことを自力で用意するか(Sagaパターンを実装)、アプリケーション層をごちゃごちゃ書くかが必要になりまあ大変です。
では、結論としてモジュラーモノリスをやめた方がいいかと言うと、これまた微妙で、
・ マイクロサービスにしてK8sを管理できる人がいない
・ それでもモノリスにはうんざりしている
・ アプリケーションを管理するのが1チーム(マイクロサービスごとに管理チームがわかれるようなことがない)
場合には挑戦しがいがあると思います。
ただし、ほぼ実装面はマイクロサービスと同じようになるということを覚悟する必要があるでしょう。
それと、マイクロサービスにできるならしてしまったほうが事例も多いしやりやすいかもしれない・・・ということを付け加えておこうと思います。
明日は、@sashihara さんによるエンジニア組織の組織開発っぽい何かの記事になります!