HubbleでCTOをやらせてもらっている藤井(@katsuya0515)です。
今年もHubble Advent Calendar 2024を無事開催でき、Hubbleの誇る優秀なエンジニアの方々が色んな記事を投稿してくれました。最終日18日目1を迎え、僭越ながら今年度最後の記事投稿をさせて頂きます。
Hubbleのとあるサービス群を合体させるという英断をし、開発効率を上げることができたお話をさせて頂きたいと思います。
背景
契約書の管理クラウドサービスを展開するHubbleですが、社内では契約書のバージョン管理部分をHubble、契約のメタ情報管理(台帳管理)の部分はドキュメントリスト(以下、Doclistと呼ぶ)という用語を使って表現をしています。
歴史を振り返ると、ビジネス版のGithub
というキャッチフレーズを掲げ、契約書のバージョン管理機能から開発が始まりました。便利!欲しい!というお言葉を受け、サービスローンチをしましたが、便利とそこに対してお金を払うか、は一線を超えたものであるという現実を知りました。
そんな中、とある大手の企業様から台帳管理機能があれば導入をしたい、という一声を頂き、このDoclistの開発が始まりました。今思えば、このDoclist開発がHubbleをシリーズA, Bへと進ませてくれた分岐点となりました。
当初の設計
当初のHubbleは、契約書のWordファイルを扱うItemモデルを軸に、バージョン情報、コメント、添付ファイル等を扱うモデルが存在していました。一方台帳管理はいわゆるExcel機能であるため、Columnモデル、Cellモデルなど新しいモデルが登場します。新規にモデルを作成することと、時代はマイクロサービスでしょ!的なノリで、別レポでRails new
をして開発が始動しました。数年運用し、結果的に下記のような課題が生まれました。
Itemの一覧を取得する内部通信
台帳機能を表現するためには、縦軸にItem、横軸にColumn、セルの内容がCellモデルになるため、HubbleからItemの情報は毎回取得する必要があります。
機能追加時にダブルコスト
またHubbleからDoclistの項目を操作したくなると、HubbleにFrontendのためのendpointを、Doclist側に内部通信のendpointを作成しなければならない。
Joinのできないquery
DBが分かれているためにjoinができず、クエリが非効率になってしまう。
マイクロサービスの利点でよく言われる、デプロイの分離をすることができたり、サーバーのリソースレベルをサービスごとに変えられるという利点はありましたが、実際には同レポからbuildされたイメージをECS上で別serviceと起動し、ALBで分散させることでこのような課題も払拭できたので、結論としてここに関しての恩恵はあまりなかったような気がします。
がっちゃんこ始動
ローカルでとりあえず合体してみる
まず最初に副作用の大枠を把握するために、ローカル環境で合体させてみました。モデルやビューにあたる部分はレポ間で独立しているためroot直下にコピーし、コントローラーはnamespaceを区切って移行しました。同時に脳内で全体像の再整理を行いました。創業から携わっているプロダクトでも忘れてしまった処理や、他の方が作ってくれた機能等があり、自分の中での再整理も兼ねて、理解に時間を費やしました。
リファクタリングとRspecの追加
移行時にネックになりそうな部分に関しては前もってリファクタリングを行いました。その際に足りてないRspecも補強し、基本的には移行後にはそのRspecが通ることで動作を担保するようにしました。
データベースを移行(AWS Data Migration)
次に行ったのはデータベースの移行をAWS Data Migrationを用いて行いました。Data Migrationは同期機能が付いているため、Doclist側のテーブルは常にHubbleに対して同期されている状態を作り出すことができ、レポ間のファイル移行はデータベースは気にすることなく行うことができました。
移行作業開始
ローカルで試した時に、起きた問題を整理しながら、実際にPRを出す時には細かい粒度で出していきました。また同時にチームメンバーにも移行開始の周知を行い、Doclist側で変更が生じた場合には一報を入れてもらい、自分自身もこまめにPRを確認することで、ローカルの時に試した差分が吸収できるように心がけました。時間がかかればかかるほどこの差分吸収作業は大変になるので、比較的リソースを集中させて行いました。
内部通信の削除/Queryの最適化
QAチームに動作確認を依頼し、無事に本番にリリース作業が終わった後も、作業は続きます。ただし、内部通信をしていた部分は、同一のサーバーにリクエストが返ってくるだけなので、この辺りから作業分担を行い最適化を少しずつ行っています。
振り返りと今後の検討事項
純粋に内部通信をしなくて良くなったことや、モデル間の呼び出しやjoin等ができたことで、開発スピードも応答スピードも改善することができたのは大きなメリットでした。とはいえ、先人の知恵であるモノリシックで大変、という言葉の本来の意味はどこかにはあるはずなので、繰り返す歴史にならないようにモジュラーモノリスを検討するなど、常にアンテナは貼っておく必要があるなと思っています。今回の学びは安易にマイクロサービスを検討するなという教訓であり、中長期的なロードマップとともに、どういう切り分けをしていくべきなのかを精度を持って議論していく必要を感じました。
最後に
2024年も様々な機能リリース、機能改善を行い、また組織的にも少しずつ大きくなってきました。今後も課題は山積みかと思いますが、全ては学びの経験という姿勢を忘れずに、日々良いプロダクト作りに努めていきたいと思います。
それではみなさん、良いお年を。
-
平日のみの投稿なので24日ですが17日目の記事としています。 ↩