はじめに
こんにちは。株式会社サイカでソフトウェアエンジニアをやっているKashitakaです。
サイカでは1年以上の期間をかけて、モノリスで動いていた自社サービスをマイクロサービス(Microservices Architecture)に作り替えました。
今回の記事では、そんなマイクロサービス化の全体像として目的や進め方、得られた結果について紹介します。
マイクロサービスという選択とその目的
複雑化したアプリケーションコードやDBスキーマの作り直し、テストコードの充実、インフラ構成の見直し等にも取り組みつつ、システムアーキテクチャとして適切なものを検討した結果、手段としてマイクロサービスを採用しました。
その意思決定の背景を紹介していきます。
変更の容易さ
システムをサービス単位で分割することで、変更による影響範囲をサービス内や、インターフェースで依存しているサービスのみに限定できます。
特にサイカのプロダクトは数理・統計処理と業務ロジックが入り混じっており、モノリシックなシステムでは数理・統計ロジックを変更するだけで業務ロジックに思わぬ影響が出てしまうことがありました。システム上のロジックやエンティティを凝集性の高いグループで管理し、インターフェースで役割を捉えることで、開発者の認知負荷を下げて変更を容易にする狙いがあります。
開発組織の拡大に伴って生産量もスケールする組織
事業の拡大に伴って開発組織も拡大をすることになります。
1つのプロダクト上で複数の機能開発が並列で動くことになったとき、個々の開発チームがシステムを変更するまでに関わるチーム外の人数を減らすことを狙っています。1機能のリリースのために、別の機能開発チームやDBチーム、基盤チームと調整して動くのではなく、個々のチームが完結して新たな価値を作ることができ、得られた成果もチームのものであるような開発組織にすることで、チームの自律性を高める狙いがあります。
挑戦しやすい土台作り
マイクロサービスであればサービス単位で利用技術を変えることが容易です。理にかなっていればサービスごとにフレームワークや言語を変えることも可能にしておき、柔軟な課題解決の手段を取れるようにしておくという狙いがあります。例えばマイクロサービス化後のプロダクトでは、数理統計部分はPythonで記述し、業務ロジック部分はGo言語を使うといったことがなされています。
また、新しい技術や新しいプロダクトの実験も小さく始めやすく、得られた知見でさらに組織が強くなる状態を目指しています。
どう作り変えたか
下記が目指したアーキテクチャの概略図になります。
マイクロサービス化前のシステム構成(構成図は省略します)はEC2インスタンスの上にPython(Django) + Vue.jsからビルドしたフロントエンドのコンテンツを配信する1つのアプリケーションサーバーと1つのDBがあるシンプルなものでした。アプリケーション自体は2016年あたりに開発が始まり、テーブル数は50を超えるそこそこの規模のものです。
マイクロサービスでは基盤にEKSを利用し、Kubernetes Cluster上で各サービスを動かしています。Goで書かれたBFFサーバーでクライアントのhttp通信を終端し、バックエンドサービスとgRPCで通信します。
gRPCサーバーもGoで記述しており、各マイクロサービス間は基本的にgRPCで通信されます。一部数理統計系の処理はPythonでhttpサーバーとなっています。データストアが必要なサービスはAWS Auroraと接続されます。
また、図では省略していますがサービスによっては、非同期処理を行うものはSQSとWorkerを持っていたり、ファイルを扱うものはAWS S3を使うなど、サービス個別の構成があります。
進める上で大事にしたこと
続いて、プロジェクトを進める上で決めた原則を紹介します。
機能追加と仕様変更をしない
コードやDBの作り直しを進める過程で、欲を出すと機能を洗練したり、仕様をシンプルにしたくなりますが我慢します。仕様の変更を入れてしまうとプロジェクトの不確実性が増しますし、現新比較の難易度が上がるので手をつけません。
ただし、変数名やDBカラム名の見直しに伴って、画面表記も改める部分が出てきます。そういった表現の変更は良しとしました。また、使われていない機能の削除も良しとしました。
現行システムの開発も並行する
長いプロジェクト期間で、現行システムに何も改善がされないのは事業としても許容し難いです。マイクロサービス化に人員を集中させつつも、現行システムの改善も並行して進めました。
1年で終わらせる
スコープを広げるといくらでも時間をかけられますが、先に期限を決めてしまい、その期間内でどこまでやるかを考えました。
プロジェクトが長期化してしまうと市場環境が変わってしまうリスクもありますし、機能開発と違って売上をすぐに生み出す開発ではないのでエンジニアのモチベーションを維持し続けるのも難しくなります。
結果
1年3ヶ月かけてマイクロサービスへの移行プロジェクトが完了しました。当初1年計画でしたが1度だけ納期を見直し、3ヶ月延長しました。理由は現行システム開発の追従分やパフォーマンス課題の修正で想定以上に時間がかかったことでした。
下記はリアーキテクチャ前後での月毎・レポジトリごとのリリース回数になります。
モノリスの時は月平均3,4回程度のリリースだったものが、マイクロサービス後は月30回程度まで上がっています。もちろん開発内容が違うので一概に比較はできませんが、システム変更の頻度が上がっていることは確かです。
得られたもの
定性的な面では、マイクロサービス化後の開発組織で得られたものに次のようなものがあります。
- 機能開発の活性化:特に既存機能から独立した新機能はサービスを新たに切り出して開発するなど、機能追加が容易になりました。
- 複数チームによる並行開発:マイクロサービス後は開発チームも再編し、3つのチームが並行して別々の機能開発を進められるようになりました。
- 採用:マイクロサービス化の取り組みそのものが「チャレンジしやすい文化」などの具体例となって、採用活動では候補者の方から共感して興味を持っていただく機会が増えました。
成功要因
最後に、マイクロサービスへの移行プロジェクトが成功する上で大事だったものを挙げます。
1つは経営やビジネス部門など、非エンジニアの重要人物の理解が十分に得られていることだと思います。システムの話なので理解を求めるのも骨が折れるところではありますが、メリットやトレードオフを説明して非エンジニア組織が納得していることが、プロジェクトを進める上で必要です。すでに触れた「現行システムとの並行開発」「1年で終わらせる」のような条件も納得感を得るための交渉材料としては大事です。
進めていく上でプロジェクトが遅延したり、データ移行でバグがあったり必ず非エンジニア部門にネガティブな影響が発生します。そういったときに理解が得られているかどうかがプロジェクトの進めやすさにもエンジニアのモチベーションにも影響します。
もう1つは採用面です。マイクロサービス化後の開発組織を見越して積極的に採用活動も並行して進めていましたが、取り組みに共感していただいた候補者には他社でマイクロサービスの運用経験があったり、今回新たに採用した技術の利用経験がある方も多く、そういった方の参画がプロジェクトの推進の力になりました。
終わりに
今回はマイクロサービス化の全体像をお伝えしました。今後は設計編やプロジェクトマネジメント編など、マイクロサービス化完了までに検討すべき具体的な項目についての詳細を紹介していこうと思いますので、乞うご期待ください!