2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
Monolith→MultiRepo→MonoRepoにいく上でのリポジトリ戦略(全1記事)
リンクをコピー
記事をブックマーク
松本宏太氏:「Monolith→MultiRepo→MonoRepoにいく上でのリポジトリ戦略」ということでSCOUTERの「@kotamat」が登壇したいと思います。
SCOUTERの紹介ですが、転職回りのサービスを展開しています。
「SCOUTER」はエージェントを誰でもできるようにするサービスです。
他には「SARDINE」というサービスをやっているんですが、これは実際にエージェント業をやっている企業向けの業務管理ツールです。
あとは現在事前登録中ですが「back check」という、面接や履歴書ではわからない転職者のリファレンスチェックサービスをやっていたりします。
基本的に、弊社はずっとLaravelとVueでやってきていて、そのあたりの話をさせていただ来たいと思います。
今回はLaravelとVueの話は出てきません(笑)。
今日しゃべる内容としては、この「リポジトリ戦略って何?」と、「どういう戦略を今までとってきたのか?」という部分の紹介と、実際の事例、メリット・デメリットといった話をしたいと思います。
「リポジトリ戦略とは?」から説明させていただきます。弊社の場合関連するユーザーがすごく多く、四すくみになっているパターンが多かったりして、それぞれがデータをやりとりする仕組みになっています。
以前「LaravelとNuxt.jsを同一レポジトリで管理する」という内容で登壇しておりましたが、やはりそれぞれのユーザーで同じドメインの処理の編集が発生するので、その領域の責務を凝縮しようと思ったときに、それぞれユーザーのリポジトリとドメインのリポジトリを分割する、みたいなことをこの前のLaravelのカンファレンスで話をしました。
これ見ていただくと線が多くて複雑な感じになっているのですが、こういう背景があったので、コードベースの拡大に伴って重複コードの扱いが大変になってきたという課題がありました。
弊社ではリポジトリ戦略をいくつか取り入れてきており、最初はこのMonolithから始まって、MultiRepoから、今はMonoRepoを検討しているような状況です。「これ何なんだろう?」ということを調べていくなかでわかったことを共有したいと思っております。
「Monolithicって何?」というところに関して。いわゆる一般的な構成かなと思います。Monolithicという命名が正しいかどうかはわかりませんが、いわゆるLaravelのアプリケーションを初期インストールするときに、LaravelのComposerのcreate appみたいな感じで入れたときのデフォルトの構成です。
そうすると、ちょっと小さいですがappとか、composer.jsonだったり、package.jsonがあって。appの中にいろいろなコードが入ってたりとか、publicの中にstaticなものが入ってたりとか、なんかいろいろ入っています。
先ほどお話した関連するユーザーが多いよところに関して、各アプリケーションで当時発生した問題としては、複数のアプリケーションでコードをシェアできないという問題が発生しました。
重複するコードがそれぞれのアプリに記述されて、例えばユーザーの取得処理がそれぞれに記述されたり、求人データの取得が、それぞれを編集しないといけない感じで、1個の機能をリリースするたびにいろいろなリポジトリを参照していました。
機能の変更に伴って各アプリケーションのコードを変更しなければならないため、過去のコードがどうしても残ってしまうということが発生していたので、その後MultiRepoという戦略をとりました。
これは何かというと、共通しているコードをパッケージ化します。重複しているコードは単一パッケージの中で管理して、それをcomposerやnpmが、LaravelやVueは対応していると思いますが、これのリポジトリでバージョン管理をしてやっていくみたいな構成にしました。
同じような構成ではありますが、例えばnode_modulesの中に、@babelと一緒にうちの@scouterincが、jobやselectionやstylebookがそれぞれ依存してたりとか。あとvendorの中にはPHP用のものが依存してたりという感じになっています。
これ、一見よさそうだなと思ってこの前もLaravelのカンファレンスで発表してたんですが、質問でも「これ、変更するの大変じゃないですかね?」という質問をされて「そうですね」という話になりました。
やっぱりこの開発手順はとても煩雑でした。
レビューする前は、子どものパッケージを更新して、子どものパッケージをdevビルドでpublishしてから、親パッケージをdevブランチにターゲットし、親パッケージをpushしてレビューください、みたいな感じになってしまいました。
リリースする前は、子どものパッケージのバージョンをセマンティックバージョンに編集して、それをpublishしてから、親をセマンティックバージョンに修正して、親をpublishすると。
「ダイヤモンド依存関係の闇」というものがあるのですが、ABCDという依存があったときに、BとCがDに依存していて、Bの更新頻度高いと、D.1が例えばVueだったときに、2.6に上がっていて、Cは2.3のままみたいな感じで、「Aって何のVueのバージョンを参照してるの?」みたいな感じで闇になるということが発生します。
大手企業ではこういったことが発生してきているので、最近ではありますが、MonoRepoという考え方がメジャーになってきました。
思想としては「1つのリポジトリに全部完結させる」というもので、パッケージの概念は今までどおり残りながら、Gitのリポジトリは1つにします。ルートのアプリケーションは、先ほど言った企業側のアプリケーションも1つのパッケージとして扱って、全部リポジトリに入れます。
構造としてはこんな感じになっていて、package1とかpackage2とかがそれぞれcomposer.jsonとかpackage.jsonを持っていながら、ルートのところにもcomposer.jsonとかpackage.jsonがある形になっています。
ルートのほうには全体のパッケージ、例えばVueとか、それぞれがVueに依存しているのでそういうところを入れつつ、パッケージごとの細かい依存はこっちに入っているみたいな感じになっています。
モノリポ化をすることによって解決できることにはこのようなことがあると思います。
バージョンが単一化させれてダイヤモンド依存の解決ができるところだったり、コードの共有のところ、例えばstylebookとか、そういうところをいろいろなリポジトリで広範囲に適用できたり。あとは依存性の管理が簡潔になったり、全体に波及する部分的な変更が容易になります。
あとは、大規模なリファクタリングやモダン化をするためのツールがだんだん作れるようになったり、ほかのチームとの連携が柔軟性が増したり連携できるようになります。
ちょっと紹介すると、依存性管理の簡潔化で、もはやセマンティックバージョンを管理するのは不要になります。都度都度のテストを通れば最新を使うようにすればいいです。
OSSとかは、外部に公開するパッケージに関しては、バージョンを切っていたりします。Laravelだと「illuminate/」というパッケージがRead Onlyのリポジトリで公開されたり、Babelだと「@babel/babel/」が公開されています。
あとは、すべてのパッケージにまたがる機能の名前空間を変えようと思ったときに、例えば「job」を「jobs」にすると、この変更自体はむちゃくちゃ簡単なんですが、すべてのパッケージがそれを依存していて、それぞれを変えているとめちゃくちゃ時間かかったりします。
1つのGitのリポジトリになるので1つのcommitで全部変えられます。こうすることで一斉置換してもテストは落ちないので、一気にリファクタリングができます。
あと、うちはまだやらないとは思いますが、Googleなんかはコードの解析をやっていて。どういう変更がバグになりそうかを機械学習したり、どういう言語がどこのプロジェクトで使われているかとか、脆弱性のパッチの適用が、1つのリポジトリで管理すると可視性が高くなり、やりやすくなります。
あとは、チーム間でいろいろなリポジトリを使っていて、1つの機能を作るにあたっても様々なパッケージに依存しなきゃいけない場合、例えばこれで言うと、求人と管理者がそれぞれのチームで使っていて依存していますが、1つの施策ごとのプルリクを作れるようになるので、境界がすごく柔軟に変えられたりします。
「デメリットってあるの?」というところについては、1個目がやっぱりコードベースがでかくなるところです。
どうしてもコードベースが大きくなっちゃうので、そこはツールの導入や規則で防ぐ必要があると思っています。
Google製のツールでいうとBazelがあったり、変更のあったところだけをビルドして、テストして、デプロイするといったことをしたりとか、cloneするときは先頭だけ引っ張ってくるようにするといった工夫が必要になります。
また、依存性の解決が簡単になりすぎる問題を挙げられています。簡単に依存性を追加できるようになってしまうので、適当に「依存性入れようぜ」みたいな感じで追加されてしまう懸念があります。最低限の依存だけに絞っていて、「このAPIはここでしか使われないよ」みたいなことを明示しないと、よりまたカオスになります。
あと、コードが社内に公開されてしまいます。1つのGitのリポジトリになるので全部見えちゃうんですけど、オープンな会社の社風じゃないとそもそも入れられません。
「じゃあ実際どこで使っているの?」というと、いろいろな企業で使われています。
OSSでいうと、VueだったらBabelに依存してたりとか、LaravelだったらSymfonyとかに依存していますがこれらはMonorepoで構成されており、Reactもこの構成です。
便利なツールの説明です、LaravelとVueに近しいところをちょっと紹介しようと思います。
「Lerna」はnpmのパッケージのモノリポに適したものになっていて、すべての一斉のpublishやコミット、pushが簡単にできます。既存のGit履歴もそのまま使えるメリットがあります。
あとは、Monorepo BuilderがSymplifyというオーガナイゼーションにあります。これはComposerベースのモノリポ化ツールで、親ディレクトリcomposer.jsonが自動生成されるんですが、コミットしないようにしてね、って書いてあったりします。これも一斉リリースができます。
あとは、Laravelのコアのところで使われているのが、このsplitsh/liteです。これはGoで作られているのですが、CLIベースでコードをディレクトリごとに分割して、Read Onlyなリポジトリにpushしてくれます。OSSでも分けたいニーズあったりするので、そういうところに使えたりします。
まとめです。
事業の特性として、この依存性がキーになってくるプロダクトでは一考の余地があるかなと思っています。うちのアプリだといろいろなパッケージを参照するので、そういうところでは割と使えるかなと思います。
あと、issueトラッカーがGitHubのissueに依存していると、そこらへんも影響されるので、開発フロー全体の設計をしっかり考えた上で導入を検討する必要があります。また、単一のリポジトリだけでいいようなプロジェクトで別にわざわざこんな構成にする必要はないなというところがまとめです。
SCOUTERではエンジニアを募集しているので、もし興味ある方いればお声がけいただければと思います。
以上です。駆け足でしたが、ありがとうございました。
(会場拍手)
関連タグ:
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術