Slide 1

Slide 1 text

© DMM.com モジュラモノリスのモジュール間通信の話

Slide 2

Slide 2 text

© DMM.com 自己紹介 2 塚原 諒 2022/04中途でDMM.com入社 所属: オンラインサロン開発部 アーキテクトチーム Twitter: @trrrrrys GitHub: trrrrrys

Slide 3

Slide 3 text

© DMM.com 話すこと 3 ● リポジトリ構成 ● モジュール間通信方法を選定した話

Slide 4

Slide 4 text

© DMM.com 4 リポジトリ構成

Slide 5

Slide 5 text

© DMM.com リポジトリ構成 5 ./apps ├── account # 会員サービス ├── payment # 決済サービス └── modular ├── bootstrap ├── cmd ├── config └── module └── salon # サロンモジュール 現状の組織だと、マイクロサービスに 合わせた組織にすることが難しいため 主要サービスのみマイクロサービス + モジュラモノリスとして運用。 事業状況や組織状況に合わせて、モ ジュラモノリスから、マイクロサービス に切り出す。 構成のPros/Consは一般的なモノレポ のものとほぼ同じ。

Slide 6

Slide 6 text

© DMM.com 6 モジュール間通信方法を選定した話

Slide 7

Slide 7 text

© DMM.com モジュール間通信方法を選定した話 7 以下の2つの呼び出し方法を検討した。 ● モジュールを直接呼び出す ● API経由で呼び出す メッセージを利用した非同期呼び出しは対象外。

Slide 8

Slide 8 text

© DMM.com ①モジュールを直接呼び出す 8 モジュールの中で、呼び出したいモジュールの公開用のIFを利用し呼び出す。 実装例(gRPC)

Slide 9

Slide 9 text

© DMM.com モジュール直接呼び出しのメリット/デメリット 9 メリット ● ネットワークを経由しないため呼び出しが高速 ● (RESTの場合) 関数を呼び出せるため型情報を利用できる デメリット ● interceptor / middleware を挟むのが難しい ● モジュールの結合度が上がる ○ (gRPCの場合は、Server用のIFを利用することでモジュール間の依存 を減らせる) ● マイクロサービスへの切り出しが大変

Slide 10

Slide 10 text

© DMM.com API経由で呼び出す 10 gRPC/REST API を利用してモジュールを呼び出す。 実装例(gRPC)

Slide 11

Slide 11 text

© DMM.com API呼び出しのメリット/デメリット 11 メリット ● モジュール間のコード上の依存がない ● モジュール間の通信にinterceptor / middlewareを利用できる デメリット ● ループバックを行うため若干のオーバーヘッドが発生 ○ gRPCの場合はシリアライズ/デシリアライズのコストも発生

Slide 12

Slide 12 text

© DMM.com 検証 12 以下サンプルを用いて検証。 ● API呼び出し https://github.com/trrrrrys/modular-monolith-example ● モジュール直接呼び出し https://github.com/trrrrrys/modular-monolith-example/tree/method-call

Slide 13

Slide 13 text

© DMM.com 検証条件 13 ● gRPCを利用 ● acount, product, payment, orderという4つのモジュールを用意し以下ユー スケースを想定 ○ orderモジュールに product_id を渡して購入処理 ○ orderモジュールはproductモジュールに在庫問い合わせ & 在庫消費 ○ orderモジュールはpaymentに支払い実行 ○ orderモジュールはアカウントサービスから住所を取得 ○ orderモジュールは購入情報保存をする ● interceptorとacount, product, pacymentモジュールのメソッドは 20 ms の 仮想の処理を実行

Slide 14

Slide 14 text

© DMM.com 検証条件(シーケンス) 14

Slide 15

Slide 15 text

© DMM.com メソッド呼び出しのトレース/Duration (100req/min) 15 OrderItemにかかった時間は 95パーセンタイルで 約110ms

Slide 16

Slide 16 text

© DMM.com API呼び出しのトレース/Duration (100req/min) 16 OrderItemにかかった時間は 95パーセンタイルで 約200ms

Slide 17

Slide 17 text

© DMM.com 検証結果 17 ● Interceptor の回数分処理時間が増える(当たり前) ○ モジュール直接呼び出しとAPI呼び出しではInterceptorの処理内容も 変わるのでそこを考慮すると結果も変わってくる ● ループバックすることによるオーバーヘッドは 2~3ms程度 ○ 実行環境によって差異はある

Slide 18

Slide 18 text

© DMM.com どちらを利用することにしたか 18 ● ②の API呼び出しを利用 ● 理由としては ○ マイクロサービスへの切り出しを視野に入れているため疎結合な方が 良い ○ 内部のサービス間通信には内部用の認証情報を用いているため、 Interceptorが利用できないのが辛い ○ ネットワークのオーバーヘッドが許容レベル ● モノリスの代用としてのモジュラモノリスであれば①も良い

Slide 19

Slide 19 text

© DMM.com まとめ 19 ● マイクロサービスへの分割も見据えてgRPC経由でモジュールの通信を行っ ている ● gRPCだとモジュラモノリスの実装が楽

Slide 20

Slide 20 text

© DMM ご静聴ありがとうございました 20