まずはドメインごとにデプロイ可能とする ~ドメイン間の依存が複雑なモノリスのモダナイズに向けて~

こんにちは。コアシステムエンジニアリング部門で受注システムの開発を担当している中尾です。

今回はモノタロウの基幹システムのモダナイゼーションの取り組みについて紹介します。 モノタロウ社内の基幹システムにはいくつか存在しておりますが、中でも古くに作られた大規模なシステムについて、機能や開発に関係するグループが多く、保守コストが増大している状況にあります。 そこで、この度、業務ドメイン毎に開発・保守できるような体制の構築とシステムの分割を実施しましたので、その取り組み内容を紹介いたします。

背景

現在、MonotaROではお客様向けのWebサイト以外に、間接業務で利用するシステムやサイトに掲載する商品や発注・在庫の管理をするシステムが存在しており、これらを社内では基幹システムと位置づけています。一般的に基幹システムはパッケージを導入していることも多いですが、MonotaROでは一部の基幹システムはWebサイトと同様に内部で開発をしています。 また、基幹システムの中にも業務ドメイン毎に個別のアプリケーションとして管理されているものもあれば、1つのアプリケーションの中に商品管理、会計処理といった複数の業務の機能が集約されたものもあります。

特に古くに作られた基幹システム(以下、大規模基幹システムX)があり、この保守が今では大きな課題となっています。この大規模基幹システムXは1つのアプリケーションであらゆる業務ドメインの機能を管理できるように造られ、管轄業務の異なる複数のグループによって長年保守が続けられてきました。しかしながら、今では会社規模も大きくなり、業務も複雑化していくなかで、1つのシステムに対して複数のグループが全く別の業務向けの開発を並行して行うことが難しくなってきており、ソースコード間の依存の複雑化や、機能単位で見た場合の可用性の低下(他の機能に巻き込まれて不具合が起きる可能性がある)といったデメリットが生じてしまっています。

図x. 大規模基幹システムXの構成イメージ 1つのサーバーで複数の機能を持つ大きなアプリケーションが動作しており、さらにソースコードレベルでの依存関係も複雑になっている。

大規模基幹システムの構成イメージ

具体的にMonotaROの大規模基幹システムXが抱えている課題の代表例を紹介します。

1機能の不具合が与える影響が大きい

1つのサーバー上で、様々なドメインの機能が動作しているため、特定のドメインでサーバーに対して負荷のかかるような障害が発生すると、たちまち他のドメインにも影響を与えてしまいます。 例えば、商品の価格登録機能で不具合が発生し、サーバーがダウンするような状態になると、顧客情報の登録や閲覧もできなくなってしまいます。

改修時にグループ間での調整が発生する

他のドメインから参照されている機能を改修する場合、そのドメインの管轄グループに対して調査や改修を依頼する場合があります。 これ自体は問題ないのですが、グループによって規模も違えば、成り立ちや文化も異なっているため、調査や改修に予想外の時間がかかってしまう可能性があります。 結果として、本来やりたい機能改修とは直接関係のない、グループ間調整のコストが大きくなってしまいます。

機能間の依存が複雑で、想定外の不具合に繋がる

また、そもそも機能間が複雑に依存しており、「なぜこの機能からこのモジュールを参照しているの」と?になるような機能も散見されます。結果的に、事前の調査では把握しきれていなかったところでモジュールが参照されており、本番リリース後に障害という形でそれが発覚することがあります。 ※大規模基幹システムXではPythonを活用しており、コンパイルを通さないため事前に依存関係や型の整合性をチェックしづらいという背景があります。

現状はこれらの課題を少しでも回避するため、リリース日をグループ毎に固定し、影響範囲を少しでも減らすようにしています。 しかし、その結果としてリリースの頻度が落ちてしまい、早くリリースしたい案件があっても週に1回しかリリースできない状況となっています。

大規模基幹システムXをドメイン単位で分割する

これらの課題を解決するため、各グループがどの機能を管轄すればよいか明確化し、自分たちの管轄範囲だけに集中できる状態を実現するべく、組織とシステムの分割を進めることとなりました。組織については、システムに先駆け、今年の4月の組織変更で、これまで境界が曖昧になっていたグループを分割し、グループと業務ドメインが明確に紐づく状態を実現しました(組織図)。 この組織に併せてアプリケーションもインフラからソースコードまで分割しマイクロサービスアーキテクチャのような構成とすることで、下図のようなグループと管轄業務ドメイン、管轄システムが明確に紐づくような状態を実現していこうとしています。

マイクロサービス化し、自分たちの管轄範囲が明確かつ最小化されることで、先述した課題を解決することができると考えています。

  • 1機能の不具合が与える影響が大きい
    • 業務ドメイン毎にサーバーが分割されるため、1サーバーでの不具合が他のサーバーに波及しないようになる。
  • 改修時にグループ間での調整が発生する
    • アプリケーションが自分たちの管轄範囲に閉じるので、他の業務ドメインの機能に対する考慮が軽減され、余分な調整が減らせる。
  • 機能間の依存が複雑で、想定外の不具合に繋がる
    • 依存関係を紐解いて分割することで、モジュール間の直接的な依存がなくなり、想定外の不具合の減少につながる。

しかし、現状でもソースコード間の依存が強くなっており、ここからマイクロサービスを目指すとなると、作業ボリュームも大きくなり、完成までに長い時間を要してしまうことが予想されました。

そこで、我々はソースコードの依存解消を一旦後回しにし、最低限ドメイン毎に開発運用できる状態を目指し、インフラと開発/運用体制の分離だけを進めることにしました(システム構成としては下図のようになるイメージ)。ソースコード以外の部分で依存を解消し、得られる効果は限定しつつも短期的に成果を出し、次のステップとしてのマイクロサービス化自体に取り組みやすくすることが狙いです。

分割のアプローチ

マイクロサービス化のファーストステップとして、インフラと開発/運用体制の分離を進めるため、このステップで実現したい事をまずは整理し、下記のように定義しました。

他グループの改修が自ドメインのプログラムに直ちに影響しないこと 他グループへの影響を考慮せずに、好きなタイミングでリリースできるようになること 特定のグループの不具合が他のグループのサーバーに波及しないこと

これらを実現するために、ファーストステップで取り組むことを下記のように決めました。ここからはファーストステップでの取り組みについて紹介していきます。

  • コンテナ化によるインフラレイヤーの分離
    • コンテナ内にインフラ部分を組み込んでしまうことで、インフラレベルの障害が他ドメインに波及しないようにする。
  • コンテナ化によるGit上のコードとデプロイされるコードの分離
    • Git上のコードとデプロイされるコードを分離することでマージ・デプロイのタイミングを自由にする。
  • 内包ソースコードの制限によるドメイン間依存低減
    • 各ドメインの管轄範囲をコードレベルで明確化し、新しい依存を検出しやすい状態を作る。

コンテナ化によるインフラレイヤーの分離

これまで共通のサーバー上で動作していたアプリケーションを業務ドメイン毎にコンテナに分けることで、特定のドメインのコンテナでの不具合が他のドメインのコンテナに波及しないようにしました。

コンテナ化によるGit上のコードとデプロイされるコードの分離

これまではGit上で管理されているソースコードが、そのまま本番環境にリリースされてしまうため、マージのタイミングに制限がありました。例えば、2日後にリリース予定の改修がマージされている場合、今日リリースを実施すると2日後予定のものが先行リリースされてしまうため、追加のリリースは必ず2日後以降にする必要がありました。

こういった状態を解消するため、機能をコンテナ化し、Git上のソースコードとコンテナに内包されているソースコードを分離しました。これと運用フローの改善を併せて、各ドメインが好きなタイミングでデプロイできる環境が実現できる見込みです。

内包ソースコードの制限によるドメイン間依存低減

各コンテナでは各ドメインの管轄機能しか動作させたくないため、それをシステム的に制限できるようにコンテナに内包するソースコードを限定するアプローチを取りました。具体的には.dockerignoreの仕組みを活用し、自ドメインの機能と現状依存しているモジュールだけをコンテナに内包するようにしました。これにより、誤って今以上の依存を増やしてしまうといったことが発生しないようにしています。

その他の取り組み

ここからは社内事情によるものが大きいため、詳しくは解説しませんが、上記取り組みのほかに下記のような取り組みも並行して進めています。

  • ブランチ戦略の変更
  • リリース運用フローの変更

これらの取り組みにより、機能がドメイン毎にコンテナで独立して動作する状態を実現し、さらには各ドメインのコンテナは自由なタイミングでデプロイができる状態になると考えています。結果として、次のステップであるマイクロサービス化もドメイン毎に進めやすくなり、よりシステムのモダナイズが促進されるだろうと見込んでいます。

まとめ

これらの取り組みは現在進行中で、まだ効果が出ていない段階のため、まずはこの取り組みを完結させ効果を出すことが我々のミッションだと考えています。 次のステップとしては、各ドメイン毎に現行のソースコードの依存を紐解き、他ドメインに対してはAPIを提供していくといったマイクロサービス化を進めていく予定です。 また、この取り組みによる効果やマイクロサービス化の話は別の記事で紹介できればと思います。

モノタロウでは随時エンジニアの採用募集をしております。この記事に興味を持っていただけた方や、モノタロウのエンジニアと話してみたい!という方はカジュアル面談 登録フォームからご応募お待ちしております。