App Engine では、Python プログラミング言語を使用してウェブ アプリケーションを作成できます。また、プロのデベロッパーが世界レベルのウェブ アプリケーションの作成に使用する数多くの Python 用ライブラリ、ツール、フレームワークを利用できます。作成した Python アプリケーションは、Google のスケーラブルなインフラストラクチャ上で動作し、大規模な永続的ストレージとサービスを利用します。
はじめに
App Engine では、あらかじめ用意されている Python インタープリタを使用して、Python アプリケーション コードを安全な「サンドボックス」環境で実行します。アプリは、この環境と通信することで、ウェブ リクエストの受信、作業の実行、レスポンスの送信を行います。
Python ウェブ アプリケーションは、WSGI プロトコルを使用して App Engine ウェブサーバーと情報を交換します。そのため、アプリケーションは、WSGI 互換のさまざまなウェブ アプリケーション フレームワークを利用できます。App Engine には、webapp2 というシンプルなウェブ アプリケーション フレームワークが含まれているため、簡単に開発を開始できます。大規模なアプリケーションの場合には、Django など、実績のあるサードパーティ製フレームワークを App Engine と連携させることができます。
インタープリタは、作成したアプリケーションに含めた Python モジュールや、Python 標準ライブラリなど、あらゆる Python コードを実行できます。ただし、インタープリタはピュアな Python 環境であるため、C コードで作成された Python モジュールを読み込むことはできません。
安全なサンドボックス環境は、サービスとセキュリティ上の理由から、作成したアプリケーションを隔離します。サンドボックス環境では、アプリは、他のアプリのパフォーマンスとスケーラビリティに影響しない処理しか実行できないようになります。たとえば、ローカル ファイル システムにデータを書き込むことはできません。また、任意のネットワークに接続することもできません。代わりに、App Engine が提供するスケーラブルなサービスを利用して、データの保存やインターネット経由の通信を行います。サンドボックス制限内では動作しない Python モジュールを標準ライブラリからインポートしようとすると、Python インタープリタは例外を生成します。
App Engine プラットフォームには、コードから呼び出せる多数のサービスが用意されています。また、アプリケーションでは、指定の間隔で実行されるタスクのスケジュールを構成することもできます。
Python 2 ランタイムを選択する
app.yaml
構成ファイルで Python ランタイム環境を指定します。アプリケーションを App Engine にデプロイするときに、このファイルが使用されます。たとえば、Python バージョン 2.7 を使用するには、次の行を app.yaml
ファイルに追加します。
runtime: python27
api_version: 1
threadsafe: true
...
1 つ目の要素 runtime
で、Python ランタイム環境を選択します。
2 番目の要素 api_version
で、使用する Python ランタイム環境のバージョンを選択します。現時点で、App Engine Python 環境のバージョンは 1
の 1 つだけです。App Engine チームで環境に行う変更が既存のコードと互換性がない場合、新しいバージョン ID でリリースします。api_version
設定を変更してアプリをアップロードするまで、アプリは選択したバージョンを使用できます。
app.yaml
ファイルの詳細と App Engine にアプリをデプロイする方法については、app.yaml
リファレンス、Python 2.7 への移行、Python アプリのデプロイをご覧ください。
サンドボックス
App Engine が複数のアプリケーションへのリクエストを複数のウェブサーバーに分散できるようにして、アプリケーションが相互に干渉しないようにするために、アプリケーションは制限された「サンドボックス」環境で実行されます。この環境でアプリケーションは、コードの実行、Datastore 内でのデータの保存とクエリ、App Engine メール、URL 取得、ユーザー サービスの使用、ユーザーのウェブ リクエストの確認とレスポンスの準備が可能となります。App Engine アプリケーションでは、次のことはできません。
ファイルシステムへの書き込み。アプリケーションは、データを永続的に保存するために、Datastore を使用する必要があります。ファイルシステムからの読み取りは可能です。また、アプリケーションでアップロードされたアプリケーション ファイルはすべて利用可能です。
遅いレスポンス。アプリケーションへのウェブ リクエストは、数秒以内に処理される必要があります。レスポンスまでに非常時に長い時間がかかるプロセスは、ウェブサーバーの過負荷を防ぐために終了します。
その他の種類のシステムコールの実行。
Python でサンドボックス化する
Python 2.7 ランタイムを使用している場合、.pyc
ファイルをアップロードして使用できますが、同じファイルの .py
と .pyc
をアップロードすることはできません。.py
または .pyc
ファイル(あるいはその組み合わせ)を含む zip ファイルをアップロードできます。.pyc
ファイルをアップロードする場合には、次の点に注意してください。
- CGI スクリプトの場合、
.pyc
ファイルをアップロードした場合も、スクリプト ハンドラではファイルの拡張子に引き続き.py
を使用する必要があります。 - デフォルトでは、デプロイ時に
.pyc
ファイルがスキップされます。.pyc
ファイルがスキップされないようにするには、app.yaml
ファイル内のskip_files
要素をオーバーライドする必要があります。 .pyc
ファイルを作成するには、Python 2.7 を使用する必要があります。開発用のマシンで Python の異なるバージョン(Python 2.6 など)を使用する場合には、バージョン 2.7 を取得して互換性のある.pyc
ファイルを作成する必要があります。
ピュア Python 2
Python ランタイム環境のコードはすべてピュア Python である必要があり、C 拡張やコンパイルが必要な他のコードを含めることはできません。
この環境には Python 標準ライブラリが含まれています。ただし、一部のモジュールは、コア関数が App Engine でサポートされないため、無効になっています(ネットワーク接続やファイル システムへの書き込みなど)。また、os
モジュールは使用できますが、サポートされていない機能は無効になっています。サポートされていないモジュールをインポートしようとした場合や、サポートされていない機能を使用しようとした場合は、例外が発生します。
標準ライブラリの一部のモジュールは、App Engine で動作するように置換、カスタマイズされています。対象となるモジュールは、2 つの Python ランタイムで異なります(下記参照)。
Python バージョン 2.7 のカスタム ライブラリ
Python バージョン 2.7 ランタイムでは、次のモジュールが置換またはカスタマイズされています。
Python 標準ライブラリと App Engine ライブラリ以外に、Python バージョン 2.7 ランタイムにはサードパーティ ライブラリも含まれています。
サードパーティ ライブラリを追加する
アプリケーションに Python のサードパーティ ライブラリを追加するには、アプリケーション ディレクトリにコードを配置します。アプリケーション ディレクトリのライブラリのディレクトリにシンボリック リンクを作成すると、そのリンクが参照されて、App Engine にデプロイするアプリにライブラリが含まれるようになります。
Python モジュールのインクルード パスには、アプリケーションのルート ディレクトリ(app.yaml
ファイルを含むディレクトリ)が含まれます。アプリケーションのルート ディレクトリに作成した Python モジュールは、ルートからのパスでアクセスできます。Python がこれらのサブディレクトリをパッケージとして認識できるように、必要な __init__.py
ファイルをサブディレクトリに作成することを忘れないでください。また、ライブラリで C 拡張が不要になるようにしてください。
スレッド
Python バージョン 2.7 では、thread
または threading
モジュールを使用してスレッドを作成できます。リクエストが終了すると、ランタイムがスレッドを結合します。リクエストの終了後にスレッドを実行することはできません。
バックグラウンド スレッド
手動または基本のスケーリングのインスタンスで実行するコードは、バックグラウンド スレッドを開始できます。このスレッドは、スレッドを生成したリクエストよりも長く存続できます。これにより、インスタンスは任意の周期またはスケジュールによってタスクを実行できるようなるほか、リクエストがユーザーに返された後でもバックグラウンドで作業を続行できるようになります。
バックグラウンド スレッドの os.environ
とロギング エンティティは、スレッドを生成するエンティティとは無関係です。
App Engine 用 SDK から google.appengine.api.background_thread
モジュールをインポートする必要があります。
BackgroundThread クラスは通常の Python threading.Threadclass
クラスに似ていますが、スレッドを生成したリクエストよりも「長く存続」できます。start_new_background_thread()
関数はバックグラウンド スレッドを作成して開始します。
ツール
App Engine 用 SDK には、アプリケーションのテスト、アプリケーション ファイルのアップロード、Datastore インデックスの管理、ログデータのダウンロード、Datastore に対する大量データのアップロードを行うためのツールが用意されています。
開発用サーバーを使用すると、ローカル コンピュータ上でアプリケーションを実行して、アプリケーションをテストできます。サーバーは Datastore サービスとサンドボックス制限をシミュレートします。また、開発用サーバーでは、テスト中にアプリが実行するクエリに基づいて、Datastore インデックスの構成を生成することもできます。
gcloud
ツールにより、App Engine で動作しているアプリケーションに対するすべてのコマンドライン操作が処理されます。gcloud app deploy
を使用すると、アプリケーションを App Engine にアップロードできます。また、Datastore インデックス構成などの個別の構成ファイルを更新することもできます。これにより、コードをデプロイする前に新しいインデックスを作成できます。また、アプリのログデータを表示して、独自のツールでアプリのパフォーマンスを分析することもできます。
同時実行とレイテンシ
トラフィックに対処するために必要なインスタンスの数に特に大きく影響するのはアプリケーションのレイテンシです。リクエストを短時間のうちに処理できるサービスであれば、1 つのインスタンスで多くのリクエストを処理できます。
シングル スレッドのインスタンスでは、同時に 1 件のリクエストしか処理できません。そのため、レイテンシと、インスタンスで処理できる 1 秒あたりのリクエスト数の間には直接的な相関関係があります。たとえば、10 ミリ秒のレイテンシでは、1 つのインスタンスで 1 秒間に 100 件のリクエストを処理します。マルチスレッドのインスタンスでは、多数のリクエストの同時処理が可能です。そのため、CPU 使用量と 1 秒あたりのリクエスト処理数の間に直接の相関関係があります。
Python バージョン 2.7 アプリは、同時リクエストをサポートしているため、1 つのインスタンスで 1 つのリクエストが完了するのを待機している間に、新しいリクエストを処理できます。同時実行性を使用すると、アプリが必要とするインスタンスの数が大幅に少なくなりますが、アプリケーションをマルチスレッド対応として設計する必要があります。
たとえば、B4 インスタンス(約 2.4 GHz)がリクエスト 1 件につき 10 M サイクルを使用する場合、1 つのインスタンスでの 1 秒あたりのリクエスト処理数は 240 件になります。リクエスト 1 件につき 100 M サイクルを使用する場合は、1 つのインスタンスでの 1 秒あたりのリクエスト処理数は 24 件になります。このような数字は理想的な条件を想定したものですが、インスタンスの処理能力という点ではかなり現実的な数字です。
環境変数
ランタイムは以下の環境変数を設定します。
環境変数 | 説明 |
---|---|
GAE_APPLICATION
|
App Engine アプリケーションの ID。この ID の先頭には「region code~」が付きます。たとえば、ヨーロッパでデプロイされたアプリケーションの場合は「e~」となります。 |
GAE_DEPLOYMENT_ID |
現在のデプロイの ID。 |
GAE_ENV |
App Engine の環境。standard に設定します。 |
GAE_INSTANCE |
現在サービスが実行されているインスタンスの ID。 |
GAE_RUNTIME |
app.yaml ファイル内で指定したランタイム。 |
GAE_SERVICE |
app.yaml ファイル内で指定したサービス名。サービス名が指定されていない場合は、default に設定されます。 |
GAE_VERSION |
サービスの現在のバージョン ラベル。 |
GOOGLE_CLOUD_PROJECT |
アプリケーションに関連付けられた Google Cloud プロジェクト ID。 |
PORT |
HTTP リクエストを受信するポート。 |
app.yaml
ファイル内で追加の環境変数を定義できますが、上記の値をオーバーライドすることはできません。