STORES Product Blog

こだわりを持ったお商売を支える「STORES」のテクノロジー部門のメンバーによるブログです。

マイクロサービス化を進めていたが、切り戻してモノリスで開発しているお話

f:id:yagi3chan:20211216141913p:plain

はじめに

この記事はhey Advent Calendar16日目の記事です。 STORES 予約 開発チーム @arrow_make です。

昨年度まで進めていたマイクロサービス化を止めてモノリスで開発するに至った過程について書いていきます。

STORES 予約 におけるマイクロサービス化

STORES 予約 には主に、管理画面(予約サイト管理者向け)と予約者画面(予約をするエンドユーザー向け)の2種類の画面があり、バックエンドのRailsサーバーでは両方の画面に向けたAPIを提供しています。
その中で主にチーム内でapi/v2と呼んでいる予約者画面に向けて提供しているAPIに連なる機能群を、Railsから切り離して一つのサービスとして独立させることを目的として始まったものと認識しています。
私自身は、マイクロサービス化の走り出し時にはまだ在籍しておらず、入社後すぐにこのプロジェクトに途中参画して約1年ほどRailsからの切り出し作業を行っていました。

マイクロサービス部分を含めたざっくりとしたシステム構成は以下の図のようになっていました。 f:id:yagi3chan:20211216155249p:plain

切り戻しを決定した背景

api/v2領域の参照系のAPIを順次切り出したサービス側に実装し、都度予約者画面からのAPIコールを切り出したサービス側へと変更していったのですが、その過程で度重なるデグレによる後戻り作業が発生し、開発生産性が無視できないレベルで低下していたこと、そもそもこの作業によって将来的な施策開発、改善のスピードを上げているイメージが持てなかったこと等を総合的に判断した結果、切り戻すことにしました。

ここからは、開発生産性が低下してしまった要因について、実際に中で手を動かしていた1エンジニアとして感じたことをベースに考察していきます。

細かい実装の良し悪しについて語ることもできるのですが、よりマクロな視点で見た時に大きく分けて3つの要因が考えられると思っており、それぞれについて論じていきます。

サービスとして切り出すスコープの定義の曖昧さ

先に、api/v2領域は、予約者画面向けのAPI群であると書きましたが、ここには予約者が予約を入れるために参照するマーチャント(店舗)情報の参照から、実際に予約を入れる予約フローまで、予約にまつわる様々な機能が含まれております。

マイクロサービス化を進めるに当たって、どのドメインを切り出すかの定義のためには、api/v2領域では曖昧すぎるかつ、これを予約ドメインを切り出すと考えた場合、現状の STORES 予約 の機能のほとんどが予約ドメインに属していると考えており、もし仮にサービスとして切り出すことに成功してた場合、その過程において「あれもこれも必要だ」と現状のRailsサーバーから提供されている機能のほとんどを切り出していたことが予想でき、これはマイクロサービス化ではなく、マイグレーションになってしまっていたのではと思っております。

STORES 予約 自体、予約の領域に特化した機能を提供しているため、ほとんどの機能が予約ドメインに属すると言ってしまっても過言ではないと思っていますが、予約システムを導入したいマーチャントのオーナーさんが抱える最大のペインポイントは予約のその先にあると考えているため、今後、予約のその先について作り込みを重ねていった結果、その部分が独自のサービスとして切り出される(もしくは初めから独立したサービスとして構築する)判断はあり得ると考えております。

開発の進め方

当時、マイクロサービス化を進めるチームと施策開発を進めるチームとを完全に分けてかつ、メンバーも固定化された状態で進めてしまったことがよくなかったなと考えております。 既存実装のコードを読みつつ、切り出したサービス側に必要な機能を実装する進め方をしていたのですが、歴史的経緯を数多く把握しているメンバーが施策開発側に偏り、かつそちらの部隊とあまりコラボレートせずに進めてしまったたことが数多くのデグレを引き起こした要因の一つだと思っています。

また、サービスを分離していく際に、DBは分離せず共有DBとして作業を進めたため、施策開発側でDBに対してかけた変更を新サービス側に適用し忘れたり、どの部分は新サービス側も参照していて、どの部分はしていないのか等を気にすることで認知負荷も高まってしまいました。

逆に共有DBだったことで切り戻し作業自体は割と単純作業でスムーズという結果オーライ的なメリットはありました。

そもそも時期尚早であった

マイクロサービス化を行うことの最大のメリットは、システム全体としてのドメイン領域は広くても、各サービスで気にすべき領域が限定されることで、エンジニア一人当たりが認知しなければいけない範囲も限定できるので、開発効率が維持しやすいところにあると思っています。

そこに対して、当時の開発チームの規模は業務委託のメンバーを含めても7~8名ほど、かつシステムのドメインもほぼ予約領域なため、切り出したところでドメインそのものの認知負荷の低減はほぼ期待できず、認知負荷は変わらないまま、さらに分散システム都合の複雑性までが持ち込まれてしまい、マイクロサービス化によって得たいメリットと真逆の効果を受けることになってしまう結果になってしまいました。

マイクサービスを含めたアーキテクチャ自体は一般的なよくある frontend-BFF-backend-api といった構成でしたが、Railsの既存実装を読み解いて backend-api 側に実装し、BFF層にデータの収集及び変換ロジックを書き、frontendの向き先をBFFへと変更する といった作業を分担せずに一人のエンジニアが全部実装していく といった開発スタイルに成らざるを得なかったことも時期尚早であったなと感じた理由の一つです。

モノリスに切り戻した今どうなのか?

マイクロサービス化を進めていた時期は、移行に手一杯であったことに加え、移行元で直したほうがいいなと思う実装を見つけても、移行先で直せばいいといった臭いものには蓋をするスタンスだったのですが、移行にかかるコストがなくなり、そこに対してしっかりと向き合う時間が取れるようになったので、足元の改善を進めつつ、その改善がすぐ実際の施策開発時に効いてくる状態になれたのではないかと思っております。

今後の展望

モノリスへの切り戻しを決定した当時は、開発チームの規模は10名いるかいないかくらいの規模でしたが、今年は採用が加速したこともあり、全体で約20名近いチーム規模になってきました。開発もこれまでワンチームで進めてきたところから2チームに分けようとしていたり、プロダクトとしても予約のその先の領域に対して踏み込もうとしていたりします。チームを分けた際の懸念として、チーム毎にドメイン知識が偏ってしまうのではないか、そのためには定期的にチームのメンバーはシャッフルしたほうがいいのではないか? といった新しい課題にも直面しています。

自分としては、このままチーム規模もプロダクトも成長していけば、これは逆コンウェイの法則*1よろしく、チームの構造にあった、すなわちチームが分離されていても生産性を維持しやすいシステム設計をすべき時期が訪れるのではないかな と期待していたりします。

*1:https://ja.wikipedia.org/wiki/メルヴィン・コンウェイ で知られるコンウェイの法則の逆で、目指すアーキテクチャを見据えた組織構造を作るべき 的な意味