Cloud Spanner ベースの Node.js アプリケーションのデプロイ
Google Cloud Japan Team
※この投稿は米国時間 2021 年 9 月 2 日に、Google Cloud blog に投稿されたものの抄訳です。
Cloud Spanner は Google の水平スケーリングが可能なフルマネージド リレーショナル データベース サービスです。金融サービス、ゲーム、小売など多くの業界のお客様が、大規模な整合性と可用性が要求されるワークロードの実行に使用しています。このブログ投稿では、OmegaTrade という株式チャート可視化ツールのサンプルを使用して、Cloud Spanner で Node.js アプリケーションをビルドしてデプロイする方法を説明します。このアプリケーションは、株価を Cloud Spanner に保存し、Google Charts を使ってチャートを表示します。Cloud Spanner インスタンスを設定する方法と Node.js アプリケーションを Cloud Run にデプロイする方法を説明し、Cloud Spanner の重要なコンセプトをいくつか示します。
まず、アプリケーションを Cloud Run にデプロイする手順を説明し、最後に、Cloud Spanner を使用するアプリケーションでの一般的なセッションの調整、接続プール、タイムアウトに関するベスト プラクティスを示します。このベスト プラクティスは OmegaTrade にも適用します。
デプロイ手順
アプリケーションを完全にサーバーレスでデプロイします。フロントエンド サービスとバックエンド サービスを Cloud Run にデプロイし、Cloud Spanner をデータストアとします。Cloud Run を使用すると、インフラストラクチャ管理が不要になり、トラフィックに応じて自動的にスケールアップまたはスケールダウンが即座に行われます。
バックエンド サービスは Node.js Express フレームワークを使用し、デフォルトの接続プール、セッション、タイムアウトで Cloud Spanner に接続します。
前提条件として、以下が必要です。
以下の権限セットのいずれかを使用して、新規または既存の GCP プロジェクトにアクセスできること:
オーナー
編集者 + Cloud Run 管理者 + Storage 管理者
Cloud Run 管理者 + Service Usage 管理者 + Cloud Spanner 管理者 + Storage 管理者
上記の GCP プロジェクトの課金が有効であること
Google Cloud SDK がインストールされ、初期化されていること
自分のマシンに Docker がインストールされ、構成されていること
自分のマシンに Git がインストールされ、設定されていること
注 - 権限が組織のポリシーで制限されていないことを確認してください。制限されていると、後でデプロイするときに問題が発生します。
では、始めましょう。
まず、gcloud 構成をデフォルトのまま設定し、この構成で GCP プロジェクトを設定します。gcloud は GCP サービスのコマンドライン インターフェースです。
出力:
目的の GCP プロジェクトにアクセスできる Google アカウントを選択して、プロンプトが表示されたらプロジェクト ID を入力します。
次に、デフォルトの gcloud 構成が正しく設定されていることを確認します。以下のコマンドで、認証の有効化と、すでに設定されている API エンドポイント URL の設定解除を行い、使用する GCP プロジェクトをデフォルトの gcloud 構成で設定します。
次に、Cloud Spanner、Container Registry、Cloud Run の Google Cloud APIs を有効にします。
Cloud Spanner のプロビジョニング: インスタンス、データベース、テーブル
gcloud コマンドで、Spanner のインスタンスとデータベースを作成します。
さらに、OmegaTrade アプリケーションに必要な 4 つのテーブルを作成します。
users(ユーザー)
companies(会社)
companyStocks(株価を追跡)
simulations(各シミュレーションの状態を追跡)
Cloud Spanner のインスタンスで INFORMATION_SCHEMA のクエリを実行して、テーブルが正常に作成されたかどうかを検証します。INFORMATION_SCHEMA は、SQL 仕様で定義されているとおり、データベース オブジェクトのメタデータのクエリを実行する際の標準の方法です。
この手順で Cloud Spanner のインスタンス、データベース、テーブルが作成されたので、OmegaTrade をビルドしてデプロイします。
Cloud Run へのアプリ バックエンドのデプロイ
Cloud Run に omegatrade/frontend サービスと omegatrade/backend サービスをデプロイする手順を見ていきましょう。先にバックエンドをデプロイしてから、バックエンド サービスの URL を使ってフロントエンドをデプロイします。
まず、リポジトリのクローンを作成します。
アプリの動作に必要な環境変数を編集します。プレースホルダ [Your-Project-ID] には、自分のプロジェクトのプロジェクト ID を入れます。
次に、Dockerfile からイメージをビルドして、GCR に push します。先ほどのように、実際の GCP プロジェクト ID に合わせてコマンドを変更する必要があります。
注 - 認証で問題が発生した場合は、実行時に表示される Google Cloud のドキュメントに記載されている手順を実行し、下のコマンドを再試行してください。
次に、バックエンドを Cloud Run にデプロイします。Cloud Run サービスを作成し、Cloud Spanner 構成の環境変数を使用してビルドしたイメージをデプロイします。この処理には数分かかることがあります。
これで、OmegaTrade のバックエンドが起動し、稼働状態になります。バックエンドのサービス URL がコンソールに表示されます。この URL は、フロントエンドのビルドに使用するため、メモしておきます。
データベースへの株式データのサンプルのインポート
以下のコマンドをバックエンドのフォルダで実行して、会社と株式のサンプルデータをインポートします。
このコマンドは、接続されているデータベースにサンプルデータを移行します。
正常に実行されると、「Data Loaded successfully」というメッセージが表示されます。
注: 重複が生じないように、必ず、この移行は空のデータベースで行ってください。
次に、フロントエンドをデプロイします。
Cloud Run へのアプリ フロントエンドのデプロイ
フロントエンド サービスをビルドする前に、バックエンドをデプロイする手順で取得したバックエンドの URL(サービス URL)を使用して、リポジトリの次のファイルを更新する必要があります。
注 - アプリケーションで「Google でログイン」を有効にする場合は、ここで OAuth を設定します。そのためには、readme のパート 6 の手順を行ってください。
ベース URL をサービス URL に変更します(/api/v1/ をそのまま追加)。OAuth を有効にした場合は、clientId を OAuth コンソールに表示された値と同じにします。
OAuth 認証情報の作成をスキップした場合は、clientId を空の文字列に設定します。その他のフィールドはすべてそのままにします。
フロントエンドのフォルダに戻り、フロントエンド サービスをビルドしてイメージを GCR に push します。この処理には数分かかることがあります。
次に、フロントエンドを Cloud Run にデプロイします。
これで、フロントエンドがデプロイされました。ブラウザでこのサービス URL を開くと、アプリケーションにアクセスできます。
フロントエンドの URL を OAuth ウェブ アプリケーションに追加して、Google アカウントでのログインを有効にすることもできます。
[OAuth 2.0 クライアント ID] で、作成したアプリケーション(OmegaTrade-Test)を開きます。[Authorised JavaScript origins] にフロントエンドの URL を追加して、保存します。
注 - ブラウザで Cookie を有効にしてください。有効になっていないと、アプリの実行がブロックされます。
スクリーンショット
お疲れさまでした。ここまでの手順で、アプリが起動し、Cloud Run で実行されます。フロントエンドの URL にアクセスして、アプリケーションを使うことができます。好きな会社のティッカーを追加して、シミュレーションをしてみましょう。データの書き込みと読み取りはすべて、Cloud Spanner が行います。
アプリのスクリーンショットをいくつか示します。
1. ログイン / 登録ビュー: 登録と認証には、Google アカウント(OAuth を有効にしている場合は OAuth で)またはメールアドレスを使用できます。正常にログインすると、ダッシュボードにリダイレクトされます。
2. ダッシュボード ビュー: このアプリは、架空の会社の株価をシミュレーションした状態で事前構成されています。ダッシュボード ビューには、シミュレーションされた株価のグラフが表示されます。
3. 会社管理ビュー: このビューで、新しい会社とティッカー シンボルを追加できます。
4. シミュレーション データ ビュー: このビューでは、既存の会社または新しく追加した会社のデータをシミュレーションできます。バックエンド サービスは、2 つのパラメータ、つまり選択された期間と行数に基づいてデータをシミュレーションします。実行中のシミュレーションの一時停止、再開、削除もできます。
これでアプリケーションがデプロイされました。次に、このアプリケーションのコードと独自のアプリケーションの両方に当てはまる Spanner の重要なコンセプトをいくつか説明します。
セッション
セッションは、Cloud Spanner データベース サービスとの通信チャネルを表します。Cloud Spanner データベースのデータの読み取り、書き込み、変更を行うトランザクションを実行するために使用します。セッションは、単一のデータベースに関連付けられます。
ベスト プラクティス - 通常、セッションを直接操作する必要はありません。セッションは、クライアント ライブラリによって内部で作成および管理され、パフォーマンスが最大になるように最適化されます。
接続(セッション)プール
Cloud Spanner では、データベースとの長期の「接続」または「通信チャネル」は DatabaseClient オブジェクトではなく「セッション」でモデル化されます。DatabaseClient オブジェクトは、内部的に、SessionPoolOptions で構成可能な SessionPool オブジェクトの中に接続(セッション)プールを実装します。
デフォルトのセッション プール オプションは以下のようになります。
ベスト プラクティス - デフォルトのセッション プール オプションを使用することをおすすめします。これが、パフォーマンスが最大になる構成です。
注 - min = max に設定すると、デフォルトでプールのサイズが最大になります。この設定は、アプリケーションがすでに最小セッション数のセッションを使用しているときに、次のセッション ブロックの作成を待つ間、ブロックされることを防ぐために使用できます。
タイムアウトと再試行
ベスト プラクティス - デフォルトのタイムアウトと再試行の構成 [1] [2] [3] を使用することをおすすめします。より積極的なタイムアウトと再試行を設定すると、バックエンドがリクエストのスロットリングを始めることがあります。
次の例では、明示的に特定のオペレーションのカスタム タイムアウトを 60 秒に設定しています(totalTimeoutMillis の設定を参照)。オペレーションの時間がこのタイムアウトを超えると、DEADLINE_EXCEEDED エラーが返されます。
まとめ
お疲れさまでした。ここまでの手順を行うと、Cloud Run にデプロイした Spanner ベースの OAuth 対応 Node.js アプリケーションが動作するようになります。さらに、Cloud Spanner で使用されるセッション、接続プール、タイムアウト、再試行に関係するさまざまなパラメータについても学習しました。ぜひアプリケーションをご自由に使ってみてください。また、コードベースもご覧ください。
Cloud Spanner 上に Node.js アプリケーションを実装するビルディング ブロックの詳細については、以下をご覧ください。
-Cloud Spanner ソフトウェア エンジニアリング マネージャー Stefan Serban