アーキテクチャの境界を越えて
セッション概要
2400万点以上の商品を取り扱う大規模BtoB ECサイトMonotaROでは、事業の急成長に伴い、既存システムの変更容易性やメンテナンス性が低下。「出荷目安アイコンの変更に9ヶ月もかかる」ほどの開発速度の低下や、APIの乱立といった課題が深刻化していました。 この状況を打開すべく全社的なモダナイゼーションを進める中で、同じ課題が再生産されることを防ぐため、我々は優れたソフトウェア設計の原則を組織の協働プロセスに応用するアプローチを試みています。 本発表では、このアプローチを支えるプラットフォームエンジニアリングの取り組み、特に開発者の認知負荷低減を目指す内部開発者ポータル(IDP)の実践例を紹介。インナーソース文化を育む取り組みの先にある、AIエージェントを活用した今後の展望についても触れます。
AI要約
マイクロサービス化とクラウド移行が急速に進む組織において、プラットフォームエンジニアリングをどう展開すべきかは多くの企業が直面する課題です。本セッションでは、2400万点以上の商品を扱う日本最大級のB2B ECプラットフォームにおいて、レガシーモノリスからの脱却と開発者体験の向上を両立させた実践例が語られています。
興味深いのは、インターナルデベロッパーポータル(IDP)の進化を、ソフトウェア設計原則という共通言語で整理している点です。シャーシパターンによる共通実装の提供から始まり、DevKit CLIによる開発ライフサイクル全体への拡大、そしてインナーソースモデルの導入へと段階的に発展した過程が、DRY原則、Convention over Configuration、開放閉鎖原則といった古典的な設計思想と結びつけて説明されます。
特に注目すべきは、147名のコントリビューターを生み出したインナーソース文化の育成や、AI時代を見据えたMCP対応など、プラットフォームチームがボトルネックにならないための工夫です。新規サービス立ち上げ時間70%削減という成果とともに、測定可能性と組織文化の両面から、実践的な知見を得られるセッションとなっています。
文字起こし
マイク入ってますね
じゃあ始めさせていただきます
皆さんこんにちはこんばんは
モノタロウの伊藤ですよろしくお願いします
もう夕方なので皆様お疲れだと思うんですけれども
もう実は眠いぞっていう方は手を挙げてください
ありがとうございます
ちょっと私の緊張がふぐれましたありがとうございます
実は緊張してるぞっていう方おられますか
私は緊張してます
始めさせてくださいよろしくお願いします
アーキテクチャの境界を越えてというタイトルで
私たちがレガシーシステムの課題をどう乗り越えてきたか
インターナルデベロッパーポータルおよびプラットフォームを
どう育ててきたかっていう実体験をお話ししようと思います
振り返ってみると結果的になんですけれども
ソフトウェア設計原則に沿った形で
何か進化してきたなという印象を個人的には思っており
ソフトウェアの設計原則っていう共通言語で
その軌跡を整理し皆様と共有できたらなと思っております
まず簡単に自己紹介させていただきます
私は2019年から2023年初頭まで見るからでバックエンジニアとして
マイクロサービスアーキテクチャの開発ですとか運用に携わってきました
そこでタッチケンを生かして
2023年からもの太郎で主にプラットフォームエンジニアとして働いております
現在はストリームアラインのチームで行っている
レガーシステムのモナナイゼーションにアラインしながら
開発者体験を向上させるIDPの構築に取り組んでいる次第です
このようなバックグラウンドを持つ私が働くもの太郎について
まず事業規模からご紹介させてください
もの太郎は間接消費資材である
どれですか
すいません
もの太郎は間接消費資材のプラットフォームでして
2400万点以上の商品を取り扱う日本最大級のB2BECプラットフォームです
1014万人のユーザー様にサービスを提供し
継続的かつ急速な成長を続けております
このように続けております
一方でこの比較的な急速な事業成長裏側で
システム面での深刻な課題が顕在化していきました
弊社システムは数年前まで
レガシーモノリスプラスいくつかのシステムを
組み合わせたようなシステムで動作して稼働していました
顕在化してきた課題は
ここに記載されているようなものが
顕在化してきておりましたと
モノリスですと変更の影響範囲が予測困難で
開発速度が一時的に低下しており
具体的には以前は1週間できていたような
ICサイトに出荷見やすアイコンというものが表示されているんですけれども
そこのアイコンをちょっと変えるよう
仕様が変えるようみたいなことに対して
9ヶ月もかかるようになっていたりしていました
次にチーム間のサイロ化ですね
各チームが独自に実装を進める結果
同じ機能のAPIが複数存在してしまっていたりしておりました
そのため出荷見やすアイコンの変更もそうなんですけれども
裏側に同じ機能を提供するAPIが複数あったりするので
それぞれを同じ変更を加えなきゃいけないみたいなことが発生するため
運用変更コストが増大していましたというのもありました
あとさらにアーキテクチャの老朽化ですね
かなりそこそこ古いシステムですので
Dockerやクマネティスなどの比較的無難な技術が
適切に使われていない利用されるところで使われていない状態も一部ありました
これらの課題を解決するために
アーキテクチャ変更に数年前から取り組む
当社弊社では取り組んでおります
マイクロサービスやモジュラーモノリスへの移行を
2,3年前から本格的に進めているところでして
加えて同時にオンプレからクラウドネイティブ
AWSやJCPへの移行という過程にあり
2つのクラウド環境を活用する必要がありました
マイクロサービス化やモジュラーモノリス化であるとか
クラウドネイティブ化はすればいいんですけれども
ただそれを無知通常にやると
結局分散化していって
無知通常に分散化していってしまうと
車輪の再発明とか再廊下でいったものを
改革化させたりすることになってしまうと思うんですよね
そこで統一基盤となるMDIと
社内で呼んでいるものを構築することになりました
これがMDIこと
モノタロウデベロッパーインターフェースと呼んでいるものです
下側がモノタロウデベロッパープラットフォームと呼んでいるものです
MDPが基盤技術群として仮想にして
MDIがその上に統一インターフェースレイヤーとして
機能する構造になっています
理想的にはストリームアラインド開発者は
MDIが提供するCLIであるとか
ウェブサイトなどを通じて
複雑な基盤技術を操作したり
その情報に簡単にアクセスできるようになるといいな
という思いでMDIを作っております
まずこのMDPの方なんですけれども
MDPはコンテナ基盤
EKSやGKSに基づいた弊社のコンテナ基盤であったり
データドックやセントリーに基づいた
可観測性の基盤
ネットワーク周りのインフラデータベースの基盤など
多岐に当たる技術で構成されています
これらの基盤技術は強力なんですけれども
それぞれが独自のインターフェースを持っていると
開発者にとっては複雑ですので
この複雑な基盤へのアクセスを簡単にするのが
MDIという位置づけです
MDIはモンタールデベロッパーインターフェースの
繰り返しの略でして
開発者と弊社のプラットフォームをつなぐ
統一インターフェースレイヤーです
開発者向けCLIをDevKit CLIと呼んでおり
呼んでおりまして
すいません図が小さいんですけれども呼んでおります
あとGoogleサイトとバックステージなどによる
デベロッパーポータルも提供しております
これらを合わせてポータル的な機能という
位置づけで提供しています
それに加えて共通ライブラリであるとか
テンプレートなどのコンポーネントを
リユーザブルコンポーネントとして提供しており
これらを合わせて全体が
モンタールデベロッパーインターフェースという風に
位置づけています
結局このMDIが1,2年前から形になってきたんですけれども
もたらした成果としましてはこのような感じになっております
新規サービス立ち上げ時の提携作業の工数が
約70%削減できています
また15以上のチームが標準化された
このMDIを通して基盤を採用しており
技術面のサイロ化の解消に
役立ちつつあるのかなという状況です
あとはMDIに対して147名の
コントリビューターが生まれている状況でして
状況でして
インナーソース文化の育みにも
貢献しているのかなと思っております
間接的ではあるんですけれども
プラットフォームエンジニアリングが
組織全体に価値を提供している
証拠になるのかなとは思っております
これからこれらの成果を
どのように実現したかを詳しく追っていく感じです
すいません これはおまけなんですけれども
インナーソース
MDIのコントリビューターが
どういうふうに推移していったかというグラフです
ここからちょっと
私の趣味全開タイムになってしまうんですけれども
プラットフォームエンジニアリングでなんで
この書籍って感じなんですけれども
SICPという書籍をご紹介します
SICPはMITで長年使われてきたプログラミングの教科書です
計算科学の基礎概念を教える古典的名著です
なぜこの本を唐突にご紹介するかといいますと
この本の割と冒頭のほうで
工学の置き換えモデルという考え方を紹介していまして
単純化した不完全なモデルから始めて
必要に応じてより精緻なモデルに置き換えていく必要が
何か開発しているとそういうことあるよねみたいなことを明確に述べているんですね
大抵のシステムはそれに該当すると思うので当然なんですけれども
私たちのプラットフォーム進化の過程も
そういうふうに結果的になっていたのかなと思っております
大雑把に言うとシャーシから始まって
DevKit CLIのようなものになって
その後インナーソースに拡大して
その後他のさらにというふうに徐々に
要件や我々がどういうふうに展開したいかという要求などに応じて
徐々に姿を変えていったという感じですね
後から詳しく見るとなんですが
それぞれドライ原則とかCOCとか開放閉鎖原則であるとか
ソフトウェアの設計原則に沿った形になっていたのかなと思っており
若干後付け感はあるんですけれども
そこあたりの設計原則を持って
どういうふうに進化してきたかを整理してみようという試みです
まず第一段階はシャーシです
まず今後シャーシに関係する原則としまして
ドライ原則というものがあります
ドライ原則はDon’t Repeat Yourselfの略で
システム設計の基本原則の一つかなと思っており
達人プログラマーという書籍に書いてあります
同じ知識やロジックをあちこちに書かない
全ての知識を単一の場所で管理する
それによって重複によるバグを防ぎ
民端性を向上させるというものです
通常の実践ですと
行動レベルでの関数であるとか
クラスの共通化であるとか
設定レベルでの環境変数の一元管理などなど
様々なレベルで
皆様のシステムでも適用されているのかなとは思っております
これが原則の一般的な説明でして
次にシャーシを作ったということで
シャーシ自体もシャーシパターンというものがありまして
このマイクロサービスパターンという書籍が
マイクロサービスパターンという書籍があるんです
ここにも記載されているんですが
シャーシパターンとマイクロサービス開発における
テンプレート共通ライバルのことで
このマイクロサービスという
ごめんなさいという書籍に載っているんですけども
車のシャーシのように各サービスは
この共通実装の上に構築されていて
そこにロギング、メトリックス分散、トレーション、エンダー、ハンドリング
ヘルスチェックなど
全てのサービスで必要な横断的関心事が
一元されるというものがシャーシパターンです
当たり前っちゃ当たり前ですけど
これドライ原則かなって後から思いました
我々のシャーシなんですけれども
このようになっております
ポインターがうまく出ないです
通信プロトコルはGRPC、コネクトRPCを採用しています
プロトコルバッファでスキーマハウスト開発を実現しており
プロトバッフを管理するリポジトリがありまして
そこのGitHub Actions上でバッフやプロトCなどを使って
コード生成を行い、サービスのクライアント向けに
各言語のパッケージマネージャー用に
そのままパッケージマネージャーでインストール可能な形に
パッケージングまで行っているという感じです
観測性のほうなんですけれども
オープンテレミトリでやっており
分散トレーシングとMetrixを収集する感じを
オープンテレミトリでやっています
構造化ロギングと合わせてシステム全体の健全性を
監視できるようにしています
これらを共通機能として
標準化してテンプレート共通ライバリー
共有CICDワークロードとして提供しており
新規サービスの立ち上げを大幅に加速しているという形です
またこれ繰り返しになるんですけれども
これによって標準化が成功して
15チーム以上のチームが
このシャーシを採用しており
コード品質がある程度均一化しましたと
同時に開発時間も70%削減という
素晴らしい成果を達成しましたと
コード実装に関する再労化問題は
これである程度解決できたかもなとは思っておりますと
ただし開発ライフサイクル全体を見渡すと
全然実はカバーできていないなというのを
シャーシを作った後に
シャーシを広めたいと思った時に気づきましたと
開発ライフサイクルにあった
まずプロジェクトを作って立ち上げるところとか
その後開発実装を
開発実コーディングを行って
その後デプロイリリースを行って
運用監視とかオフィスが補修を行いますと
シャーシのカバー範囲はここだけなんですと
これだとちょっとシャーシを展開するにしても
ちょっと魅力が薄いというところもありますし
開発生産性の貢献にも不十分だねということで
第2段階として
デブキットCLIというものを作りました
振り返ってみると
これはコンベンションオーバーコンフィギュレーションと
ファサードパターンだったなと思っております
コンベンションオーバーコンフィギュレーションというのは
開発者の認知不可を削減して
本質的な開発に集中可能にする一つのパターンですけども
これは設定より規約という意味でして
合理的なデフォルト設定を提供することで
開発者の認知不可を大幅に削減しようというもので
Ruby OnRaysで有名になったのかなと思っております
開発者は標準から張る出る場合のみ設定を書けばよい
標準通りだったらほとんど設定しなくてよいということで
ボイラープレートコードを削減して
本質的な開発に集中できるようになるというものです
COCを使っていない場合はいろんな設定を
いちいち全部書きますみたいな感じですね
分かりやすく言うと
COCを使っている場合はデフォルト設定を使用するので
細かい設定はいりませんという感じです
この原則を開発ライフサイクル全体の効率化つかめに
適用したものがDevKit CLIだったのかなと思っております
開発
実装した後CICDであるとかロギングの設定であるとか
モニタリングの設定というのは
各プロジェクトコードに毎回設定することになるんですけど
結局設定する内容ってほとんど
社内の仕組みに乗っかるという
もしかしたら社内のお約束ごとに従うということになると
結構似たようなことを結局設定するんですね
毎度
その部分をいちいちプロジェクトごとに設定するのは
非効率でしたので
そこでCOC
結果的にCOCに適用ということで
DevKitを開発したという感じですね
DevKit CLIを使うと
開発者は最小限の設定で開発を始められるようになる
という感じです
DevKit CLIは一応ステージをカバーしてますという感じです
こちらが具体的な実際の画面なんですけれども
左側は今朝撮ったスクリーンショットなんですけども
左が新規プロジェクトの作成画面で
DevKitコマンドを実行するだけで
テンプレートを選択していく
で即座にプロジェクトが立ち上がる感じですね
見えないですけど
言語であるとか
どこにデプロイしますかみたいなものを
環境を設定すると
それに応じたテンプレートから
実際にそのプロジェクトに関するリソースが
ある程度自動で作られるというイメージですと
完全に自動化はされてないところもあるんですけども
イメージとしてはそういうものです
どちらも複雑な
右側がですね
こうやってプロジェクトイニットした後
プロジェクトがGitHub上にも作られるんですけども
そのGitHub上に作られたプロジェクトを
プルしてきて
他のメンバーがそのプロジェクトを利用できるという感じにするのが
右側の画面に映っているコマンドです
どちらも複雑な設定ファイルを書く必要をなくすので
COCなのかなと思っております
DevKit CLIで自動構成される典型的なシステム構成は
このような感じになっているんですけども
ご興味がある方はスライドがアップロードされた後に
ぜひ見ていただけると幸いです
すいませんそれが小さすぎて
あとはですね
こちらDevKitの別の機能なんですけども
プルリコードのプレビュー環境を生成するコマンドもあったりしますと
あとはですね
テンプレートといっても
いろんなバリエーションがあり得るよねということでして
例えばPythonですと
WebアプリケーションでもAPIでも
WSGIとかASGIとか
いろいろ種類があると思うんですけど
それぞれごとのテンプレートを
ここで選択できるようになっていたりしますと
もしニーズに合うテンプレートがない場合は
ちょうど説明するインナーソース的な感じで
新しいテンプレートをコントリビューションすることも
可能な感じになっております
次に唐突なんですけど
ファサードパターンについて説明します
ファサードパターンというのは
このGang of 4のデザインパターンという
オブジェクト飛行プラグラミング関連では有名な書籍ですけども
このデザインパターンの書籍に記載されているパターンで
これはクライアントに対して
何か機能に何かシステムにアクセスするクライアントに対して
内部の複雑性を意識させずに
システムを利用できるようにするもの
内部の変更を
こちらの内部の変更を
クライアントへの影響を最小限にするように
間にファサードを挟みましょうというパターンです
本来のファサードパターン
オブジェクト飛行プラグインのパターンなんですけども
結果的にDevKit CLIは
この発想プラットフォームのために
適用した感じなのかなと思っております
後から見ると
分断された開発体験
各基盤への分断されたアクセスを
このDevKit CLIによって
ファサードによって
統合された体験に近づけたのかなと思っております
第3段階インナーソースなんですけれども
まず
多分ここに集まられているような方は
インナーソースという言葉をご存知だと思うんですけど
一応確認しますと
インナーソースという言葉をすでに知っていたという方は
手を挙げてください
そうですよね
ほとんど皆さんの方
皆さん知っておられたので
ちょっと逆にびっくりしました
じゃあ飛ばしますか
インナーソースというのは
社内でオープンソース的に
共通のコンポーネントとかライブラリを
進化させていくぞみたいな感じの手法ですね
組織の中のいろんな部門とかの境界を超えて
知識共有とか改善を効率的にやっていきましょう
みたいな感じかと思います
このインナーソースというアプローチが
実は開放閉鎖原則の組織レベルの実現に近いのかなと思っております
開放閉鎖原則とはなんですけども
このクリーンアーキテクチャーという書籍などに記載されているんですけども
ソフトウェアエンティティは拡張に対して開いており
修正に対しては閉じているべきという原則ですと
別の言い方をしますと
新機能を追加する際は拡張で対応できて
その際既存コードは修正する必要はないというものですと
システムの安定性を保ちながら機能を成長させていく
というパターンというか原則ですね
実現方法としてはオブジェクト思考の場合ですと
インターフェースとか抽象クラスとか
ポリモフィズムとかコンポジションなどなどで
実現するのかなと思っております
インナーソース的なものをこのMDIに適用しようという
ところを考えた状況なんですけれども
プラットフォームチームはボトルネックになってしまう問題ですね
いろんな開発チームからいろんな要求が
プラットフォームチームに当然
プラットフォームなので集中していろいろ来てしまいますと
そうするとプラットフォームチームだけで
それに対応しようとすると
結局それの要求への対応の待ち時間が発生して
それぞれのストリームアラインのチームの
開発効率が著しく低下することになりがちだと思うんですよね
それを解決するためにインナーソースにしようという発想ですね
特に弊社マルチプラットフォームかつマルチ言語の環境でして
非常に要求が多様ですと
そこでインナーソースモデルを導入して
MDIとかMDPをインナーソースで開発しようみたいな感じですと
プラットフォームチームは
コア機能の機能の維持であるとか安定性を維持したり
標準的なツールをアプリチームに提供したりというところである意味に閉じて
アプリチームは独自機能を追加したい場合とか
標準とは外れる何かをしたい場合は
プルリクエストで貢献するという形を取りますと
一応これで理論的にはプラットフォームチームのボトルネックが解消されるのかなと思っております
あとですね
興味深いことに
いや興味深いかどうか分からないですけども
この構造は同時に依存性逆転減速も実現しているのかなと思っておりますと
チームとプラットフォームが貢献のプロトコルという抽象に依存することで
チーム間の結合度がある意味低下しているんじゃないかなと思っております
このインナーモデル
インナーソースモデルをどういうふうに提供したかなんですけども
先ほどだいぶ前のスライドと話がかぶってしまうんですけれども
もう残り1分ですか
この後大量にスライドが残っておりまして
これはいつもの私のパターンなんですけども
ちょっと飛ばし飛ばして話させてください
インナーソースなんですけども
テンプレートのバリエーションという機能がありまして
これでコア変更すでに新タイプを追加できたりしますと
結果的に147名の方がコントリビューとしてくださりましたと
第4段階なんですけども
移動性逆転減速は中小に移動するようにしましょう
ビジネーションロジックは具体的な実装に直接移動しないようにして
インターフェースなどの中小に移動することで
柔軟性テストアビリティーを実現しますというものなんですけれども
あとは測定可能性の原則というものがありまして
ピーター・ドラッガーやデミングさんは
測定できるものしかもデミングできないみたいなことを
解いたと言われていますと
同時に本当に重要なものは測定できないとも警告されていますと
測定可能なものを活用しつつ
数値ができない価値も大切にしようということで
モダルアナリゼーションスコアというものを最近やっていまして
もうオーバーしていますか
モダルアナリゼスコアというのは
名前の通りシステム技術的なケーパビリティのモダルアナリズ度合いを測るスコアでして
14項目のもので採点するという感じです
この技術スタッカーの詳細が異なるシステム間で
同じ基準で同じ度合いを評価できるようにある程度なるというので
抽象に依存するようになりましたというのと測定可能になって
モダルの定義は人によって異なって進捗を測定できなかったのを
こういう定義をもたらすことによって進捗を測定できるようになりましたという感じですね
あとこれをPDCAサイクルで回して改善していくという使い方ができるかもしれません
ということを話しておりますと
ここでパラダイム転換がありまして
AIができましたよね
そうすると人中心の主導のSDLCからAI中心のSDLCになっていくので
そこにも今後は対応していく必要がありますよねということです
すでにある程度対応していまして
DevKit CLIにMCP機能がありまして
ここでいろんな情報とかをできるようになっておりますと
あと統合APIカタログなども整備したりしております
あとモノキューブエージェントというものがありまして
コンテナキューブのトラブルシュート用のエージェントもあったりします
あとは飛ばします
学びはこういうふうに一応ソフトウェア設計原則とかで
説明はそれぞれのステップの説明はつくなと思ったりおります
今後はAI活動に貢献する基盤整備やAI中心の開発パラダイムに対応した課題にも取り組んでいきますので
同じような課題に取り組む皆様と経験を共有して共に学び続けていければ幸いです
モノタロウではなくてもいいですよという方はぜひ一緒にプラットフォームを育てましょう
よろしくお願いします
以上です
ご講演ありがとうございました
それではこれよりQ&Aセッションに移ります
非常にたくさんの質問をいただいておりますが
残り時間の都合上1,2問ほどお受けできればと思います
まず1つ目がドライ原則を適用するときに過度な共通化はスタンプ結合のような処理の複雑さがコンポーネントに内包されると考えるのですが
過度な共通化にならないように気をつけられたこととかありますか
まずこの機能を提供する側のチームもそんなにリソースがないので
まず何からやろうかと慎重に考えてやりますと
あとですね私もともとストリームアライド側で働いていたので
あんまり基盤側にいろんな機能がありすぎると
選択の自由がなりすぎてつまらないなと思い実は思っていたりするので
そこは過度な共通化にならないようなスタイルで自然と機能を提供することを気をつけていたというか
自然にそうなっていたのかなと思っています
ありがとうございます
続いての質問です
MDIがもたらした成果
数値成果の算出方法が気になったので教えてください
70%削減しましたよみたいなやつですか
あれはですね
何を自動化したいよね何を手助けしたいよねっていうことを把握するために
各ステップをバーッと項目バーッと抜き出していって
今かかっている時間このぐらいだよねみたいなものを自分だけでやるんじゃなくて
ストリームアライドチームの方とかにも書いてもらって
その上で結局このCLIで自動化された部分とかをどういう効果あったかをバーテリストしていって
その結果比較すると70%ぐらい削減していたよねっていう感じで算出しています
ありがとうございます
最後の1問に参ります
スライド作成でAI使いましたか
スライドが綺麗だったのでどうやって作ったのか気になりました
あのですねフルAIです
ただし最後の方結局細かい調整をしなきゃいけなかったんですけども
それが意外と面倒で
本当に効率化していったかどうかは
若干怪しいところもあったりはします
ありがとうございます
以上でセッションを終了いたします
皆さんもう一度盛大な拍手をお願いいたします
ありがとうございました