App Engine スタンダード環境ユーザーのための App Engine フレキシブル環境

このガイドでは、スタンダード環境に慣れているユーザーのためのフレキシブル環境を紹介します。それぞれの環境の類似点と重要な相違点を説明し、両方の環境を使用するアプリケーションにおすすめの一般的なアーキテクチャを紹介します。

スタンダード環境で使用可能なサービスをフレキシブル環境の類似サービスにマッピングするには、スタンダード環境からフレキシブル環境へのサービスの移行をご覧ください。

類似点と重要な相違点

App Engine のデプロイ、サービス、スケーリング インフラストラクチャは、両方の環境で提供されます。重要な違いは、環境がアプリケーションを実行する方法、アプリケーションが外部サービスにアクセスする方法、アプリケーションをローカルで実行する方法、アプリケーションのスケーリング方法です。これらの違いの概要については、環境の選択でも確認できます。

アプリケーションの実行

スタンダード環境では、アプリケーションはサンドボックス内の軽量なインスタンスで実行されます。このサンドボックスでは、アプリケーションにできることが制限されます。たとえば、アプリケーションはディスクに書き込む、またはホワイトリストに登録されていないバイナリ ライブラリを使用することができません。またスタンダード環境では、アプリケーションで使用できる CPU とメモリ量のオプションが制限されます。これらの制限のため、App Engine スタンダード アプリケーションのほとんどは HTTP リクエストに素早く応答するステートレス ウェブ アプリケーションとなる傾向があります。

対照的に、フレキシブル環境ではアプリケーションは制限の少ない Google Compute Engine 仮想マシン(VM)の Docker コンテナで実行されます。たとえば、任意のプログラミング言語の使用、ディスクへの書き込み、任意のライブラリの使用、さらに複数プロセスの実行が可能です。またフレキシブル環境では、インスタンスに対して任意の Compute Engine マシンタイプを選択して、アプリケーションがより多くのメモリと CPU にアクセスできるようにすることができます。

外部サービスにアクセスする

スタンダード環境では、アプリケーションは通常、組み込みの google.appengine API を介して Datastore などのサービスにアクセスします。ただし、フレキシブル環境ではこれらの API は使用できなくなりました。代わりに、Google Cloud クライアント ライブラリを使用します。これらのクライアント ライブラリはどこでも使用できるので、アプリケーションのポータビリティが高まります。 フレキシブル環境で実行されるアプリケーションは、通常は大きな変更を加えずに、必要に応じて Google Kubernetes Engine または Compute Engine で実行できます。

ローカルでの開発

スタンダード環境では、通常、App Engine SDK を使用してアプリケーションをローカルで実行します。SDK はアプリケーションの実行を処理し、App Engine サービスをエミュレートします。フレキシブル環境では、アプリケーションの実行に SDK は使用されません。代わりに、フレキシブル環境向けのアプリケーションは、どこででも実行できる標準的なウェブ アプリケーションとして記述する必要があります。前述のように、フレキシブル環境ではアプリケーションは Docker コンテナで実行されるだけです。つまり、ローカルでアプリケーションをテストするには、アプリケーションを直接実行することになります。たとえば、Django を使用して Python アプリケーションを実行するには、python manage.py runserver を実行します。

もう一つの重要な違いとして、ローカルで実行されるフレキシブル環境のアプリケーションは、Datastore などの実際の Cloud Platform サービスを使用します。ローカルでのテストには別のプロジェクトを使用し、可能な場合にはエミュレータを使用してください。

スケーリングの特徴

どちらの環境も App Engine の自動スケーリング インフラストラクチャを使用しますが、スケーリングの方法は異なります。スタンダード環境では 0 個のインスタンスから数千のインスタンスまで素早くスケーリングできます。一方、フレキシブル環境では、各アクティブ バージョンに対して実行中のインスタンスが少なくとも 1 つ必要であり、トラフィックに応じてスケールアップするのに時間がかかる場合があります。

スタンダード環境では、カスタム設計の自動スケーリング アルゴリズムが使用されます。フレキシブル環境では、Compute Engine オートスケーラーを使用します。フレキシブル環境は、Compute Engine で使用可能なすべての自動スケーリング オプションをサポートしているわけではありません。デベロッパーは、さまざまな条件下でアプリケーションの動作をテストする必要があります。たとえば、CPU バウンドのアプリケーションが、リモート サービスを呼び出す際のレイテンシが長くなって I/O バウンドになった場合、自動スケーリングがどのように応答するかを確認する必要があります。

ヘルスチェック

スタンダード環境では、インスタンスにトラフィックを送信するかどうかの決定にヘルスチェックは使用されません。フレキシブル環境では、アプリケーション デベロッパーは独自のヘルスチェック ハンドラを作成できます。これはロードバランサによって、トラフィックをインスタンスに送信するかどうかや自動修復を行うかどうかの決定に使用されます。デベロッパーは、ヘルスチェックにロジックを追加する際に注意する必要があります。たとえば、ヘルスチェックによって外部サービスを呼び出し、そのサービスで一時的な障害が発生すると、すべてのインスタンスが異常になり、カスケード障害が発生する可能性があります。

過負荷時のリクエストのドロップ

カスケード障害を回避するための戦略の一環として、過負荷時にアプリケーションへのリクエストをドロップできます。この機能は、スタンダード環境のトラフィック ルーティング レイヤに組み込まれています。フレキシブル環境における QPS の非常に高いアプリケーションを開発する場合は、同時リクエストの数を制限して過負荷トラフィックをドロップする機能をアプリケーションに組み込むことをおすすめします。

フレキシブル環境のアプリケーションがこのタイプの障害の影響を受けないことを確認するには、最大インスタンス数を制限したバージョンを作成します。その後、リクエストがドロップされるまで、トラフィックを徐々に増やします。過負荷時にアプリケーションがヘルスチェックに失敗しないことを確認します。

Jetty ランタイムを使用している Java アプリでは、過負荷トラフィックをドロップするように Quality of Service フィルタを構成できます。アプリによって同時処理されるクエストの最大数と、この機能によってリクエストがキュー内に入っている時間の長さを設定できます。

インスタンス サイズ

フレキシブル環境のインスタンスでは、CPU とメモリの上限をスタンダード環境のインスタンスよりも高く設定できます。これにより、フレキシブル インスタンスではメモリと CPU をより多く消費するアプリケーションを実行できます。ただし、単一インスタンス内のスレッド数が増加するため、同時実行に関するバグの発生する可能性が高くなります。

デベロッパーは、フレキシブル環境インスタンスに SSH で接続してスレッドダンプを取得することで、このタイプの問題のトラブルシューティングを実施できます。

$ ps auwwx | grep java
$ sudo kill -3 
$ sudo docker logs gaeapp

リクエストの最大タイムアウト

スタンダード環境ではリクエスト タイムアウトが設けられていますが、フレキシブル環境ではそのような期限はありません。リクエストが無期限にハングアップして最終的にウェブサーバーのすべてのスレッドが消費されることを回避するには、次のようにします。

  • 外部サービスを呼び出す際に、タイムアウトを指定します。

  • サーブレット フィルタを実装して、許容範囲を超える長い時間(60 秒など)を要するリクエストを強制終了します。フィルタによってリクエストが強制終了された後、アプリが一貫した状態に戻ることを確認してください。

スレッドの管理

Java 8 より前のスタンダード環境の Java ランタイムでは、使用できるのが App Engine スタンダード環境 SDK を使用して作成されたスレッドに限られていました。 アプリケーションを第 1 世代の Java スタンダード環境のランタイムからフレキシブル環境に移植するデベロッパーは、ネイティブ スレッドのライブラリを使用するように切り替える必要があります。非常に多くのスレッドを必要とするアプリケーションの場合、スレッドを明示的に作成するよりも、スレッドプールを使用したほうが効率的に実行される可能性があります。

トラフィックの移行

スタンダード環境には、レイテンシの急増を最小限に抑えるために、新しいバージョンへのトラフィックの移行を徐々に行うトラフィック移行機能が用意されています。トラフィックを新しいバージョンに切り替える際にレイテンシの急増を確実に回避する方法については、トラフィックの移行に関するドキュメントをご覧ください。

単一ゾーンの障害

スタンダード環境のアプリケーションはシングルホームです。つまり、アプリケーションのインスタンスはすべて、単一の可用性ゾーンに存在します。そのゾーンで障害が発生した場合、アプリケーションは新しいインスタンスを同じリージョン内の別のゾーンで起動し、ロードバランサはトラフィックを新しいインスタンスにルーティングします。リクエストの読み込みと Memcache のフラッシュにより、レイテンシが一時的に急増します。

フレキシブル環境のアプリケーションは、リージョナル マネージド インスタンス グループを使用します。つまり、インスタンスはリージョン内の複数の可用性ゾーンに分散されます。単一のゾーンに障害が発生した場合、ロードバランサはそのゾーンへのトラフィックのルーティングを停止します。インスタンスを可能な限りホットな状態で実行するように自動スケーリングを設定している場合は、自動スケーリングによってインスタンスがさらに作成される前に、短時間の過負荷状態が発生します。

費用の比較

スタンダード環境とフレキシブル環境で実行されるワークロードの費用の比較には、さまざまな要因が関係します。たとえば、次のようなものです。

  • MCycle ごとに支払われる料金。
  • CPU プラットフォーム機能。これは 1 MCycle ごとに実施できる作業に影響します。
  • インスタンスを各プラットフォームでどれだけホットな状態で実行できるか。
  • デプロイの費用。プラットフォームごとに異なる可能性があり、またアプリケーションに継続的デプロイを使用している場合は高額になる可能性があります。
  • 実行時のオーバーヘッド。

各プラットフォームでのワークロードの費用を決定するには、実験を行う必要があります。フレキシブル環境では、変更が費用に影響するかどうかを実験によって判断する際に、アプリケーションのコスト効率の代わりにコアあたりの QPS を使用できます。スタンダード環境では、アプリケーションのコスト効率に関するリアルタイム指標を取得できるメカニズムは用意されていません。変更した後、1 日の請求サイクルが完了するのを待つ必要があります。

マイクロサービス

スタンダード環境では、X-Appengine-Inbound-Appid リクエスト ヘッダーを使用してアプリケーション間の安全な認証を行うことができます。フレキシブル環境にそのような機能はありません。アプリケーション間の認証を安全に行うには、OAuth の使用をおすすめします。

デプロイ

一般に、スタンダード環境でのデプロイはフレキシブル環境でのデプロイよりも短時間で済みます。フレキシブル環境での既存バージョンのスケールアップは、新しいバージョンのデプロイよりも迅速に行えます。新しいバージョンのためのネットワーク プログラミングは通常、フレキシブル環境でのデプロイにおけるボトルネックとなるためです。フレキシブル環境で迅速なロールバックを行うための戦略のひとつに、正常稼働した実績のあるバージョンを単一インスタンスにスケールダウンして維持しておく、という方法があります。そうしておけば、そのバージョンをスケールアップし、トラフィック分割を使用してすべてのトラフィックをそのバージョンにルーティングするだけで済みます。

フレキシブル環境を使用する際の判断基準

フレキシブル環境は、スタンダード環境を補完することを目的としています。既存のアプリケーションをスタンダード環境で実行している場合、通常、アプリケーション全体をフレキシブル環境に移行する必要はありません。それよりも、アプリケーションの中でより多くの CPU やメモリ、特殊なサードパーティ ライブラリやプログラムを必要とする部分や、スタンダード環境では不可能な動作を必要とする部分を見極めてください。 アプリケーションにそのような部分があったら、その部分だけをフレキシブル環境を使用して処理する小さな App Engine サービスを作成します。 スタンダード環境で実行されている既存のサービスでは、HTTP、Cloud Tasks、Cloud Pub/Sub を使用して他のサービスを呼び出すことができます。

たとえば、既存のウェブ アプリケーションをスタンダード環境で実行していて、ファイルを PDF に変換する新機能を追加する必要がある場合には、フレキシブル環境で実行する、PDF への変換のみを処理する別のマイクロサービスを作成できます。このマイクロサービスは、1 つまたは 2 つのリクエスト ハンドラのみで構成されるシンプルなプログラムとして作成できます。このマイクロサービスでは、変換に役立つ任意の Linux プログラム(unoconv など)をインストールして使用できます。

メイン アプリケーションは、スタンダード環境に残ったまま、HTTP を使用してこのマイクロサービスを直接呼び出すことができます。また、変換に時間がかかることが予想される場合は、Cloud Tasks または Cloud Pub/Sub を使用してリクエストをキューに追加できます。

次のステップ

スタンダード環境でアプリが使用するサービスをフレキシブル環境の類似サービスにマッピングする