マイクロサービスへの移行はStrangler patternで
ここからは「資料室」を例に、移行をどう進めたかを具体的に見ていこう。この「資料室」という機能は、保育・教育施設で取り扱うさまざまな資料を保護者が閲覧できるようにアプリ上に公開するためのサービスとなる。サービス自体は単純だが、既存アプリとの連携、特にこれまで蓄積されたデータも継続して扱えるようにするところが難点となる。
従来はモノリシックなシステムが同じリソースで稼働していた。またあらゆる機能が1つのデータベースに蓄積されるような形になっていた。新サービスでは、新しいリソース上で稼働させ、独自のデータベースを持たせ、新しいスタックを用いることにした。ただしデータは古いデータベースにあるものも扱えるようにしなくてはならないため、必要な情報を抜き取り、新しいサービスの形に変換するデータ同期バッチを中間に立てることにした。
技術スタックとしては、バックエンドはドメインを型で表現しやすく、nullチェックも厳格であり、メンバーに経験者がいたKotlinを選んだ。フロントエンドはNuxt.js、インフラはECS(コンテナ)、CI/CDはGitHub Actions、E2EテストはGaugeとPlaywrightとした。
リプレイスへのアプローチで最も重視したのは「安全にリリースすること」なので現行システムとできるだけ疎結合にした。ほかにもビッグバンリリースにしないこと(徐々にリリースする)、容易に運用できるようにテストに力を入れることも重視した。リリースから数年経ちユーザーが求めるものが見えてきたので、このタイミングでフロントもリプレイスできるように、フロントも切り出した。
モノリシックなシステムからマイクロサービスに切り離す時に参考にしたのが「Strangler pattern」で、これは新旧のサービスを並行稼働させながら徐々に切り替えていく方法だ。新しい機能を小さい単位で作り、トラフィックをコントロールすることでユーザーを徐々に新しい方へと誘導していく。コドモン プロダクト開発チーム エンジニア Dimitrov Chavdar氏は「本番環境に未完成の成果物をリリースできて、トラフィックを切り替えるまで何も影響がないのがうれしい」と話す。
新しいサービスを一部のユーザーから徐々にリリースすることをカナリアリリースと呼ぶ。何か問題が生じても影響範囲は少なく、安全な旧サービスにトラフィックを誘導すればいい。実際に新サービスでエラーになれば、自動的に旧サービスを利用するようにフェイルセーフする仕組みがあれば、ユーザーは「何かいま画面が遷移したかな?」くらいで大きな問題にはなりにくい。