はじめに

「会議室が予約されているのに誰も使っていない」「空いているか確認するためにGoogleカレンダーからわざわざチェックする」
——こうした社内の非効率を解消するために会議室予約システムを Google Cloud で構築し、ついにリリースすることができました!
本連載では、このシステムの設計・実装を通じて得た Google Cloud の実践的な使い方を3回に分けて紹介します。

  • 第1回(本稿): サーバーレス設計
  • 第2回: ネットワーク・セキュリティ設計
  • 第3回: データ分析基盤と DevOps

システム概要

本システムは、各会議室に設置した iPad から入退室操作・即時予約を行い、Google カレンダーと連携して会議室の利用状況をリアルタイムに管理するシステムです。
主な機能は以下の4つです。

  • 会議室のリアルタイム状態表示(空き・利用中・予約済み)
  • Google カレンダーとの自動同期(1分間隔)
  • iPad からのワンタッチ予約・入退室操作
  • カラ予約の自動キャンセルと Slack 通知

設計の中心に置いたこと:ゼロメンテナンス

本システムは社内ツールです。
開発リソースをアプリの機能開発に集中させるため、インフラの運用負荷をできる限りゼロに近づけることを最優先に設計しました。
具体的には「サーバーレス・フルマネージドサービスを最優先に選ぶ」という方針を全体に貫いています。

全体アーキテクチャ

まず全体像を示します。
Google Cloud のフルマネージドサービスを中心に、3層構成で設計しています。

登場する Google Cloud のサービスをカテゴリ別に整理すると以下のとおりです。

カテゴリ サービス
コンピュート Cloud Run, Cloud Scheduler, Cloud Workflows
データストア Cloud Firestore
認証・セキュリティ Identity-Aware Proxy, Workload Identity Federation, IAM
ネットワーク VPC, Private Google Access, Cloud DNS, Cloud NAT
DevOps Artifact Registry, Cloud Logging, Cloud Storage
データ分析 Firebase Extensions, BigQuery, Looker Studio

本稿では コンピュートデータストア(Firestore) に絞って解説します。
認証・ネットワークは第2回、分析基盤と DevOps は第3回で扱います。

Cloud Run

アーキテクチャの選択

本システムのアプリケーション実行環境として Cloud Run を選びました。

選定の判断軸は3つです。

  1. スケール・トゥ・ゼロ:アクセスのない夜間・休日はインスタンスが自動的に0まで縮小し、コストが発生しない
  2. フルマネージド:OS パッチ、ランタイムのバージョン管理、負荷分散といった運用作業がすべて不要
  3. コンテナベース:フロントエンドとバックエンド(BFF/API)を1つのコンテナにまとめ、デプロイパイプラインとランタイムを一本化できる

特に3点目は本システムの構成上の大きな決断でした。
フロントエンドとバックエンドを Next.js(Node.js)で統一し、単一コンテナとして Cloud Run に乗せています。
これによりデプロイ先が1つになり、CI/CD の構成が大幅にシンプルになります。

スケーリング設定とトレードオフ

パラメータ 設定値 意図
最小インスタンス数 0 夜間・休日のコストをゼロに抑える
最大インスタンス数 5 初期運用段階での過剰スケーリングを防ぐ

最小インスタンスを0にすることで、アクセスがない時間帯のコストは発生しません。
代わりにコールドスタート(初回起動時のレイテンシ)が発生します。
本システムは社内ツールであり、始業時の最初の1リクエストに数秒かかることは許容できるという判断です。

最大インスタンス数を5に抑えているのは、初期運用段階では実際の負荷特性が不明なため、安全策として低めに設定しています。
同時接続の想定は最大30リクエスト程度であり、現時点では十分な値です。

Cloud Run が担う3つの役割

Cloud Run 上で動くアプリケーションは、内部的に3つの責務を持っています。

Cloud Scheduler + Cloud Workflows

定期バッチをどう設計するか

会議室の予約情報を Google カレンダーから取得する処理と、カラ予約を検出して通知する処理は、1分間隔で定期的に実行する必要があります。
この定期実行を実現するために Cloud SchedulerCloud Workflows を組み合わせています。

Cloud Workflows を挟む理由

Cloud Scheduler だけでは「1つのエンドポイントを叩く」ことしかできません。
本システムでは2つの API を 順序制御しながら 実行する必要があります。
Cloud Workflows を挟むことで以下のメリットが得られます。

  • 順序保証:カレンダー同期が完了してから空予約判定を実行できる(最新データで判定できる)
  • IAP 認証の自動処理:Cloud Run の前段にある IAP(Identity-Aware Proxy)を通過するための署名付き JWT 生成を Workflows 側で処理できる
  • 実行ログの可視化:各ステップの成功・失敗が Cloud Console 上で確認できる

Cloud Scheduler から直接 Cloud Run の内部 URL を呼ぶ構成も技術的には可能ですが、IAP 認証の処理と複数 API の順序制御を Scheduler 側に押し込むと設定が複雑になります。
Workflows を間に置くことでそれぞれの責務が明確に分離されます。

Google カレンダーとのデータ連携:Webhook ではなくポーリングを選んだ理由

予約データのマスターはカレンダー

本システムでは、会議室の予約操作は社員が普段使っている Google カレンダーから行います。
カレンダーを予約データの「マスター」として位置づけ、システムはそれを読み取って同期する構成です。

同期方式の選択

Google Calendar API には変更通知を受け取る Webhook(Push Notifications) も用意されています。
しかし本システムでは ポーリング(1分間隔での定期取得) を採用しました。

方式 メリット デメリット
Webhook 変更をほぼリアルタイムに受け取れる 受信エンドポイントの常時待機が必要・有効期限の定期更新が必要
ポーリング シンプル・運用が容易 最大1分の遅延が発生する

1分のラグが許容できるかどうかがポイントです。
本システムにおいて「カレンダーで予約を変更してから iPad に反映されるまで最大1分かかる」は、業務上起きうるケースが少ないため問題ないと判断しました。
一方、Webhook は受信エンドポイントの管理や有効期限の定期更新といった運用負荷が発生します。

ゼロメンテナンスという設計方針に基づき、シンプルなポーリングを選択しました。

Cloud Firestore:ニアリアルタイム同期の要

Firestore を選んだ理由

データベースには Cloud Firestore(Native モード)を採用しました。
選定の決め手は Snapshot Listener によるリアルタイム同期機能です。

カレンダー同期 API が Firestore にデータを書き込むと、Snapshot Listener を通じて 接続中の iPad に即座にデータがプッシュされます
これにより iPad がポーリングを行う必要がなく、会議室の状態変更が自動的に画面に反映されます。

「カレンダーのポーリングは1分間隔だが、iPad への反映は書き込みと同時」という構成です。
ポーリングの遅延は最大1分ありますが、Firestore への書き込みが発生した瞬間に iPad 側は更新されます。

ネットワーク設計との連携

Cloud Run から Firestore へのアクセスは、パブリックインターネットを経由せず VPC 内のプライベートアクセスで行います。
これについては第2回のネットワーク設計編で詳しく説明します。

コスト試算

Firestore の無料利用枠は読み取り50,000回/日・書き込み20,000回/日・削除20,000回/日です。
本システムの規模(数十名が使用する社内ツール、数部屋の会議室)では、1日あたりの操作数が無料枠の範囲に十分収まる見込みです。
データベースコストがほぼゼロで運用できる点も Firestore 選定の理由の一つです。

こちらのブログも併せてご覧ください!
会議室予約アプリでCloud SQLではなくFirestoreを選んだ理由

まとめ

本稿では Cloud Run・Cloud Scheduler・Cloud Workflows・Firestore を中心に、サーバーレス設計とリアルタイム同期の仕組みを解説しました。

ポイントをまとめると:

  • Cloud Run のスケール・トゥ・ゼロでコストを最適化し、フロント/バック統合で運用を一本化
  • Cloud Scheduler + Cloud Workflows の組み合わせで、IAP 認証を含む複数 API の順序実行を宣言的に管理
  • ポーリング + Firestore の組み合わせで、Webhook の運用負荷を避けながらニアリアルタイム同期を実現

次回は、このシステムのネットワークとセキュリティ設計を解説します。
IAP によるゼロトラスト認証、VPC を使った Firestore へのプライベートアクセス、Workload Identity Federation によるキーレス CI/CD などを取り上げます。