詳細
- 概要
- Dodam は、500 名以上のユーザーを持つ校内スマートスクールプラットフォームです。これまで手作業で一つひとつ行っていた業務(外泊承認、深夜自習の申請、学事日程の管理など)を Dodam で処理します。
- 30 日間で最大 162.82k リクエスト、平均 5.4k リクエスト/日 規模のサービスサーバーを開発・保守しました。
- Web サービスは校内の学生のみが利用できます。
- モノリシック構造の限界と MSA への移行
- 既存の単一アプリケーションにおいて、サービス間の結合とデプロイの非効率という問題を経験しました。
- 1 つのプロセス内ですべてのドメインがリソースを共有していたため、特定ドメインの障害が全体に影響を及ぼしていました。
- わずかな修正であっても全体のビルドと再デプロイが必要になるという構造的な限界がありました。
- ドメイン境界を基準に 11 個のサービスへ分割し、Spring Cloud Gateway を単一のエントリポイントとして配置してルーティングと OAuth2 認証を処理しました。
- サービス分割に伴う通信アーキテクチャの設計
- サービスの分割に伴い、これまでメソッド呼び出しで処理していたロジックをネットワーク通信へ置き換える必要がありました。
- 即時の応答が必要な認証フローには gRPC を、結果を待つ必要のないイベント(ユーザー作成、通知送信など)には Kafka を適用しました。
- Core モジュールにイベントスキーマと Topic を共通定義し、サービス間のメッセージ契約を一元化しました。
- サービスごとに異なる言語を採用できるポリグロット構成を実現できました。
- 多数のサービスにおけるデプロイ・運用の複雑さの解消
- サービスが増えるにつれ、毎回すべてをビルド・デプロイすることが非効率になっていました。
- 変更されたサービスのみを検知してビルドする Delta Build と、サービスごとの順次 Rolling Update を適用しました。
- K3s クラスター(Worker Node 2 台)を構成し、トラフィックが集中する主要サービス(Gateway、Auth、User)にのみレプリカを分散配置することで、限られたインフラの中で高可用性を確保しました。
- バックエンドインフラ構成
- 主要機能は Spring Boot サーバーが担い、トラフィックの高い API は Redis を用いてキャッシュします。
- Dodam アカウントによる OAuth 機能を提供するため、Token サーバー、OAuth サーバー、OpenAPI サーバーなどを運用しています。
- CI/CD 構成
- PR 作成時に GitHub Actions で Gradle のビルドとテストを自動実行し、コード品質を検証します。
- develop ブランチへのマージ時に Docker イメージをビルドし、開発サーバーへ Docker Compose でデプロイします。
- main ブランチへのマージ時に Docker イメージをビルドし、kubectl apply で K3s クラスターへ本番デプロイします。
- 所感
- 全校生徒が使用するサービスを自ら運用し、機能の要望や障害に迅速かつ正確に対応する過程で、安定したサービスの重要性を実感し、コード品質と保守性を高めるよう努めました。
- MSA への移行によってトラフィックが集中するサービスのみを選択的にスケールアウトできるようになり、サービス単位での独立したスケーリングが運用効率に大きな差を生むことを実感しました。