モジュール分割の進捗どうですか?
\スニダンを開発しているSODA inc.の Advent Calendar 2024 22日目の記事です!!!/
この記事は何?
以前、
イベントストーミングを実施して、3日間で境界づけられたコンテキストを定義した話
という記事を記載して8ヶ月ほど経過しました。
あっというまですね。
この8ヶ月の間にモジュール分割の全体像を改めて整理したので、進捗と合わせて書いていこうかなと思います。
前提
バックエンド開発には大きく分けて2つの問題があります。
日本とグローバルのインフラとアプリケーションコードが分離されている
弊社の技術スタックとしては上記のようになっております。
見て分かる通り、日本とグローバルのインフラとアプリケーションコードが分離されています。
この状況だと、日本とグローバルで同じ機能を提供したい場合に、それぞれのアプリケーションコードに機能改修が必要になり2倍の開発工数が必要になります。
アプリケーションコードの複雑度が高い
現状、スニダンでは全チームが複数のドメイン領域を横断して開発しています。
例えば、決済機能を追加する場合、販売、決済、外部連携システムが関わってきます。
外部連携システムは別のチームが開発した領域のため、 外部連携システムの話をその領域に詳しいチームにヒアリングしつつ、販売、決済をまるっとキャッチアップして開発するということが起きています。
ドメインが都度複数チームで機能改修のたびに変更されていくため、アプリケーションコードがツギハギだらけになりがちです。
そして、複雑度や結合度が高まり、結果として認知負荷も高くなります。
その領域の認知負荷が高くなると、リファインメント、設計、実装、review、QAなど多くの開発プロセスに遅延が発生し、リリースまでのリードタイムが悪化していきます。
実際にサイクロマティック複雑度の数値も、月日の経過とともに悪化していることが確認できています。
なぜモジュール分割が必要なのか?
前提に記載した問題を解決するためです。
もっと具体的にいうと、下記が目的になります。
- 1機能開発でグローバルに影響を与えられる状態にする
- 日本とグローバルのそれぞれの機能開発のリードタイムの短縮し、ユーザーへの価値提供と市場からのフィードバックをより早いサイクルで回せるようにする
一般的なモジュール分割でいうと、モノリスなアプリケーションから特定のドメイン領域ごとに何らかのアーキテクチャに則って切り出すことを指すかなと思います。
弊社の場合、ただモジュールとして切り出すだけではなく、日本とグローバルのアプリケーションの統合も実施していくことになるので、難易度が高くなっています。
また、日本とグローバルのアプリケーションの統合を鑑みて、社内では「グローバルプロダクト化」というPJT名で推進しています。
グローバルプロダクト化のDoD(完成の定義)
2つのゴールを設定しました。
- 商品カタログ、出品、一次在庫、販売、決済を日本とグローバルの共通のモジュールとして切り出されており、それぞれのモジュールが疎に連携されている状態
- 切り出された各モジュールに対してチームのオーナーが決まっている状態
対象モジュールについて
上記に記載していないコンテキストについては、一旦スコープ外としています。
理由としては、商品カタログ、出品、一次在庫、販売、決済領域に対する機能開発が多いことと、グローバルとJPでビジネスプロセスが一致してそうなことが見えているためです。
なので、優先的にこの領域を切り出すこととしました。
配送や鑑定等のコンテキストを切り出す必要がないという判断をしたわけでなく、グローバルプロダクト化のPJT完遂後に再度検討するイメージです。
また、販売モジュールを切り出すにあたって、クーポン等を先にモジュールとして切り出す必要があるかもしれませんが、それは追って確認し、必要に応じて切り出していく予定になっています。
モジュールごとに、オーナーチームを用意する意図
こちらは端的に言うと、開発リードタイムの短縮のためです。
現状の問題に記載したように、各チームが複数のドメイン領域を横断的に開発するスタイルの場合、複雑度が高くなリードタイムが遅くなっていきます。
そこで、モジュールを切り出したチームがそのままオーナーとなってもらい、そのモジュールを継続的に育ててもらう予定となっています。
そして、以降の機能開発時にはそのモジュールを中心に開発してもらうことになります。
切り出したモジュールが増えてくると、並列に複数のモジュールチームが一切に一つの機能を開発できる状態になります。
先に記載した新しい決済機能を追加する場合、
- ASIS
- 外部連携システムの話をその領域に詳しいチームにヒアリング
- その領域を考慮しつつ、販売、決済をまるっとキャッチアップして開発
- TOBE
- 下記のチームが並列に連携しつつ開発
- 販売モジュールチーム
- 決済モジュールチーム
- 外部連携モジュールチーム
- 下記のチームが並列に連携しつつ開発
TOBEのほうが圧倒的に開発が進みそうですよね。
この状態を目指していきたいと思っています。
期日目標
2025年の年度末を目標にゴール達成を目指します。
モジュール分割はすでに開始しており、最初の1個目のモジュールを切り出している最中です。
その実績を鑑みると、このゴール目標の難易度は非常に高いのですが、敢えて現状の外側にゴール設定しました。
関わる人全員がこのゴールに執着できれば、最終的な成長率(実績)が最大化すると考えています。
アーキテクチャ
前提として、これらのゴールを達成するためのアーキテクチャは、高凝集、疎結合なアーキテクチャにする必要があります。
それを踏まえて、モジュラモノリスを採用することにしました。
図で表現すると下記の様になります。
濃いオレンジがモジュールで、薄いオレンジのモノリスのアプリケーション内にコンテキストごとにモジュールとして切り出されている状態を表しています。
DBも最終的には、モジュールごとに論理的にスキーマを分け、排他的な所有権を保持する状態を目指します。
なぜ、モジュラモノリスを選んだの?
結論としては、可逆性が高いからです。
他にもマイクロサービス、SOA、Self Contained Systemsなどでも実現はできると思いますが、
これらはインフラ構造が機能やサービス単位で独立して作られます。
切り出すモジュールの単位は、ドメイン分析やリリース後に運用しながら変わっていくものなので、インフラまで切り出した後に、切り出す単位を変えるとなると改修コストが高くなります。
なので、一旦モジュラモノリスを経由するのがベストだと判断しました。
運用しながらモジュールが安定してきた段階で、かつ、必要があれば別のアーキテクチャを検討するのが良いかと思っています。
どのモジュールから切り出すことにしたの?
結論、「商品カタログ」から切り出しています。
商品カタログとは、弊社の商品関連のマスタを取り扱うコンテキストです。
商品名、商品画像、品番、ブランド、定価、カテゴリなどの要素が該当します。
なぜ、商品カタログを選定したのか?
理由としては、いくつかあります。
- 他コンテキストとの依存関係的に分割しやすそう
- コアドメインの出品、一次在庫、販売は別のコンテキストに依存しているし、依存されているので移行の難易度が高い
- 商品カタログと決済は別のコンテキストに依存していない
- 商品マスタはGlobalとの連携がすでにProduction環境で動作済み
- Globalとの統合に向けて必要なことがある程度明確
- マスタの変更がJPとGlobalで取り扱いやすい状態になっていることに対する事業貢献度が高い
- 現在のマスタは歴史的な積み重ねにより煩雑な状況で、扱いづらい状況
詳細は下記のLT資料にも記載しているので、良かったら見てみてください。
【技術的負債LT会】私たちの技術負債最前線~過去と未来について~
進捗どうですか?
仕様調整、ドメインモデリング、シン商品マスタの設計を終え、シンテーブルへの書き込みが今年度末に完了する予定です。
来年1月初旬から、モノリス側から商品マスタ参照を切り替えていき、1月末で一旦完了予定です。
8月から着手して、紆余曲折ありましたがようやく形になりました。
PJTを進めるうえで優先度が低いものは後回しにしているので、2月移行も頃合いをみながら改善活動を実施していく予定です。
商品カタログについても何記事にかにできるぐらいのエピソードがありますので、追って記事にできればなと思っています。
次に切り出すモジュール
2月中旬ぐらいから出品モジュールを切り出す予定となっています。
出品が選定されたのは、依存先の商品カタログがモジュールとなっていることと、
詳細は書くことはできませんが、ビジネス戦略としても出品に力を入れていくためです。
最後に
このPJTを進めるにあたって、最終的なモジュールにチームがアサインされた状態のゴールから逆算すると圧倒的に人が足りていません。
一般的なモノリスからモジュラモノリスへの移行と違い、グローバル側のシステムとの統合も実施する必要があり難易度は非常に高いと思いますが、多くのチャレンジができる環境だと思っています。
興味がある方はぜひ、↓のEntrance Bookから応募していただけると幸いです。
待ってるよ!
株式会社SODAの開発組織がお届けするZenn Publicationです。 是非Entrance Bookもご覧ください! → recruit.soda-inc.jp/engineer
Discussion