App Engine はリクエストのドメイン名を使って、受信したリクエストがあなたのアプリケーション宛のものかを判断します。
http://your_app_id.appspot.com
のドメイン名を持つリクエストは、your_app_id
の部分をIDに持つアプリケーションにルーティングされます。
全てのアプリケーションは無料でappspot.com
ドメイン名を取得します。
appspot.com
ドメインはsubdomain-dot-your_app_id.appspot.com
形式のサブドメインをサポートしており、
ドメイン名の一部のsubdomain
部分には、(.
を除く)任意の文字列が使用されます。
この形式のサブドメイン宛のリクエストは、あなたのアプリケーションにルーティングされます。
Google Appsを使って、カスタムトップレベルドメインを設定できます。 Google Appsでは、あなたのビジネス用ドメインのサブドメインをGoogle メールやGoogle サイトのような様々なアプリケーションに割り当てることができます。 また、 App Engineアプリケーションをサブドメインに紐付けることもできます。 便宜上、Google AppsのドメインはアプリケーションIDを登録するタイミングで設定でき、それ以降は開発者コンソール上から設定できます。 詳細については Google Apps URLにあなたのアプリケーションを配置する を参照してください。
これらURL宛のリクエストは全て、あなたが開発者コンソール上で既定として選んだバージョンのアプリケーションへ送られます。
各バージョンのアプリケーションはそれぞれ独自のURLを持っているので、新しいバージョンのアプリを既定バージョンにはせずに配置したりテストしたりできます。
バージョン固有のURLは、appspot.com
ドメイン名に加えて、アプリの設定ファイルに書かれたバージョン識別子を使って生成されます。
このように: http://version_id-dot-latest-dot-your_app_id.appspot.com
。
また、バージョン固有URLの付いたサブドメインを使用することもできます。: http://subdomain-dot-version_id-dot-latest-dot-your_app_id.appspot.com
リクエストで使用されているドメイン名は、アプリケーションに渡されるリクエストデータ内に含まれています。
アプリへのアクセスに使用されているドメイン名に応じてアプリで異なる応答をさせたい場合は (特定のドメインへのアクセスを制限したり、公式のドメインへリダイレクトするような)、
アプリケーションコード内でのドメイン宛のリクエストデータ( Host
リクエストヘッダのような)を確認し、それに応じて応答することができます。
あなたのアプリが モジュールを使用している場合、リクエストを特定のモジュール(必要に応じてそのモジュールの特定のバージョン)に割り振ることができます。 モジュールのアドレス指定に関する詳細情報については、リクエストをモジュールへルーティングするを参照してください。
注意:
2013年4月以降から、 Google ではappspot.com
でホストされたダブルワイルドカードドメイン(すなわち、*.*.appspot.com
)向けのSSL証明書は発行しません。
アプリケーションへのHTTPSアクセスにそうしたURLを使用している場合は、アプリケーションのロジックを".
"ではなく"-dot-
"を使ったものに変更してください。
例えば、アプリケーションmyapp のv1にアクセスするにはhttps://v1-dot-myapp.appspot.com
を使用します。
https://v1.myapp.appspot.com
を使用した場合は証明書が一致せず、URLと証明書が正確に一致することを想定しているUser-Agentではエラーが発生します。
App Engine はあなたのアプリケーション宛のウェブリクエストを受信した時、アプリケーションのapp.yaml設定ファイルで説明されているように、そのURLに対応するハンドラースクリプトを呼び出します。
あなたのアプリケーションがバックエンドを使用している場合、backends.yaml
に定義されているハンドラースクリプトを呼び出すこともできます。
詳細については バックエンドの設定 を参照してください。
Python 2.7 ランタイムは、後方互換性のためにWSGI 標準と CGI 標準をサポートしています。
WSGI がお勧めで、Python 2.7の機能のいくつかはこれがないと動作しません。
アプリケーションの スクリプトハンドラーの設定によってリクエストがWSGI を使って制御されるか、CGIを使って制御されるかが決まります。
Python 2.5 ランタイムでは常に CGI 標準を使用します。
App Engine はアプリケーションのインスタンスを複数実行し、各インスタンスはリクエストを処理するために独自のウェブサーバを持っています。 リクエストは任意のインスタンスにルーティングされ、同一ユーザーからリクエスト連続してきても、常に同じインスタンスに送られるとは限りません。 インスタンスの数は、トラフィック数の変化に応じて自動的に調節されます。
アプリケーションをスレッドセーフにするとconcurrent requestsが有効になり、App Engineは複数のリクエストを各ウェブサーバに平行して割り振ることができます。
そのやり方は、同時要求を使用するで説明しているように、
app.yaml
にthreadsafe: true
と設定するだけです。
同時要求 は Python 2.7 のアプリでのみ使用でき、スクリプトハンドラがCGIを使っている場合には使用できません。
サーバは、リクエストのURLとアプリの設定ファイルのURLパターンを比較して、呼び出すアプリケーションオブジェクトを決定します。 それから、WSGI 標準で定義された引数を使用してアプリケーションオブジェクトを呼び出します。 アプリケーションアブジェクトはリクエストに対して適切なアクションを実行し、それから応答の準備をし、その応答を文字列のリストとして返します。
ほとんどのアプリケーションは、WSGI リクエストを制御するためにwebapp2のようなフレームワークを使用しています。
webapp2
は Python 2.7 ランタイムの一部として含まれています。
サーバは、リクエストのURLとアプリの設定ファイルのURLパターンを比較して、実行するPython ハンドラスクリプトを決定します。 それから、リクエストデータが埋め込まれたCGI環境でスクリプトを実行します。 CGI 標準で説明されているように、サーバーは環境変数と標準入力ストリームにリクエストデータを設置します。 スクリプトはリクエストに対して適切なアクションを実行し、それから応答の準備をし、その応答を標準出力ストリームに乗せます。
ほとんどのアプリケーションは、CGI リクエストを解析してCGI 応答を返すために、Python標準ライブラリcgi モジュールや、CGI プロトコルを使用できるウェブフレームワーク(webappのような)といったライブラリを使用しています。 環境変数や入力ストリームデータの形式についての詳細は、CGI のドキュメントを参照してください。
以下はユーザーのブラウザにメッセージを表示するハンドラースクリプトの例です。 メッセージのタイプを識別するためのHTTPヘッダと、出力するメッセージの内容が表示されます。
print "Content-Type: text/plain"
print ""
print "Hello, world!"
受信した HTTP リクエストには、クライアントによって送信された HTTP ヘッダが含まれています。 安全上の理由から、ヘッダによってはアプリケーションに届く前に中間プロキシによってサニタイズされたり修正されたりします。
以下のヘッダはリクエストから削除されます。:
Accept-Encoding
Connection
Keep-Alive
Proxy-Authorization
TE
Trailer
Transfer-Encoding
また、appspot.com
や *.appspot.com
以外のドメインへ送られるリクエストからはStrict-Transport-Security
ヘッダが削除されます。
これらのヘッダはクライアントとサーバ間のHTTPデータ転送に関連し、アプリケーション側ではノータッチの領域です。
例えば、サーバはAccept-Encoding
リクエストヘッダの値に従って、自動的にgzip圧縮された応答を送信することがあります。
アプリケーション自身は、ユーザー受信できるコンテンツエンコードが何なのかを知る必要はありません。
アプリを動作させるために、App Engine は全てのリクエストに対して以下のヘッダを追加します:
X-AppEngine-Country
X-AppEngine-Country
ヘッダに記載された国情報は異なる可能性もあります。
アプリケーションでは、特別な国コードZZ
(不明の国)も処理できるようにしてください。X-AppEngine-Region
X-AppEngine-Country
の示す国と照らし合わせないと意味が分かりません。
例えば、国が"US"で地域が"ca"の場合は、 "ca"は"カリフォルニア"を意味します。カナダではありません。
有効な地域の値の全一覧は、 ISO-3166-2標準にあります。
X-AppEngine-City
mountain view
となるでしょう。
このヘッダについては、有効な値の一覧はありません。X-AppEngine-CityLatLong
App Engineサービスでは必要に応じてリクエストヘッダを追加することもあります。:
タスクキューサービスでは、リクエスト内のタスクとそれに関連するキューの詳細を伝えるために、リクエストに追加ヘッダ を追加します。
Cron サービスからのリクエストにも以下の HTTP ヘッダが含まれます:
X-AppEngine-Cron: true
詳細についてはcronのURLのセキュリティを保護する を参照してください。
他のApp Engine アプリケーションから来たリクエストには、リクエストを作成したアプリを識別するための以下ヘッダが含まれています。:
X-Appengine-Inbound-Appid
詳細についてはアプリ識別のドキュメント を参照してください。
App Engine はRequest
のスクリプトハンドラを呼び出し、それが完了するまで待ちます。; 標準出力ストリームに書き出される全てのデータはHTTP 応答として送信されます。
以降で説明するように、応答を生成する際にはいくつかの制限が適用され、応答がクライアントへ返される前に変更されることもあります。
動的な応答のサイズは32MBに制限されています。スクリプトハンドラーがこの制限以上の応答を生成した場合、サーバは500 Internal Server Error ステータスコードの空応答を返します。 この制限はBlobstore やGoogle クラウドストレージから届くデータの応答には適用されません。
App Engine では、リクエストを処理しながらクライアントへ増加チャンクのデータを送信する、ストリーミング応答はサポートしていません。 あなたのコードから送信される全てのデータは上記で説明されている方法で収集され、単一のHTTP応答として送信されます。
クライアントが、圧縮(gzipped)コンテンツを受信できることを示すHTTPヘッダをリクエストに付けて送信した場合、 App Engine は自動的にハンドラー応答データを圧縮し、適切な応答ヘッダを付けます。
クライアントが圧縮応答を確実に受け取ることができるかを判別するために、Accept-Encoding
リクエストヘッダとUser-Agent
リクエストヘッダの両方を使用します。
クライアントを改造する際には、Accept-Encoding
ヘッダとUser-Agent
ヘッダの両方にgzip
の値を指定することで、クライアントが圧縮された応答を受信できることを相手に伝えることができます。
また、応答のContent-Type
は圧縮が適切かどうかは判別するために使用されます。;通常は、テキストベースのコンテンツは圧縮されますがバイナリのコンテンツは圧縮されません。
App Engineによって応答が自動的に圧縮された場合、応答には Content-Encoding
ヘッダが追加されます。
以下のヘッダは無視され、応答から削除されます:
Connection
Content-Encoding
*Content-Length
Date
Keep-Alive
Proxy-Authenticate
Server
Trailer
Transfer-Encoding
Upgrade
* App Engineによって応答が圧縮される場合は再び追加されます。
さらに、*.appspot.com
以外のドメインが送信する応答からはStrict-Transport-Security
ヘッダが削除されます。
名前や値にASCII ではない文字を含むヘッダも削除されます。
以下のヘッダは応答では追加や置き換えが行われます:
Cache-Control
とExpires
と Vary
これらのヘッダでは、プロキシ(インターネットサービスプロバイダーのような)とブラウザを中間媒体とするキャッシュポリシーを設定します。
あなたのスクリプトがこれらのヘッダを設定した場合、応答にSet-Cookieヘッダが設定されるか管理者アカウントを使って署名したユーザー向けに応答が生成されない限りは、キャッシュは維持されたままになります。
静的ハンドラーは設定ファイルに従ってこれらのヘッダを設定します。
あなたがCache-Control
を設定しない場合は、サーバでprivate
と設定してVary: Accept-Encoding
ヘッダを追加します。
応答にSet-Cookieヘッダが設定されていた場合、Cache-Control
ヘッダには private
の値が設定され(既にprivateよりも厳しいアクセス権が設定されていないのであれば)、
Expires
ヘッダには現在の日時が設定されるでしょう (それが過去の日付でなければ)。通常はこれでブラウザは応答をキャッシュできますが、プロキシサーバではキャッシュを行いません。これにはセキュリティ上の理由があります。応答のキャッシュを公に行うと、別のユーザーが同じリソースに続けざまにリクエストを送信して最初のユーザーのクッキーを取得できてしまうからです。
Content-Encoding
Content-Type
によっては、前述のようにサーバは応答の本文を自動的に圧縮します。
この場合は、 Content-Encoding: gzip
ヘッダを追加すると本文が圧縮されることを表します。
詳細については応答の圧縮の項目を参照してください。Content-Length
や Transfer-Encoding
Content-Length
ヘッダを常に無視します。
Content-Length
には本文の長さ(圧縮が適用される場合は圧縮後の長さ)が設定されるか、もしくはContent-Length
が削除されます。
チャンク転送エンコーディング を使用します(Transfer-Encoding: chunked
ヘッダが追加されます)。Content-Type
アプリケーションによって設定されなかった場合、サーバは既定の Content-Type: text/html
ヘッダを設定します。
Date
Server
Google Frontend
の値が設定されます。
デベロップメントサーバではこれに Development/x
の値が設定され、 x にはバージョンナンバーが入ります。
管理者アカウントでログインした状態であなたのサイトにアクセスした場合、App Engineは応答ヘッダ内にリクエストごとの統計情報を入れます:
X-AppEngine-Estimated-CPM-US-Dollars
X-AppEngine-Resource-Usage
リソース消費統計情報を含んだ応答はキャッシュできません。
アプリケーションの応答に X-AppEngine-BlobKey
ヘッダが設定されている場合、オプションのX-AppEngine-BlobRange
ヘッダと合わせて、
blobstore blobのコンテンツの一部または全部で本文を書き換えるのに使われます。
アプリケーションでContent-Type
を設定しない場合、BLOB のMIME タイプが設定されます。
Range が必要な場合は、応答ステータスは206 Partial Content
に変更され、Content-Range
ヘッダが追加されます。
X-AppEngine-BlobKey
ヘッダと X-AppEngine-BlobRange
ヘッダは応答から削除されます。
blobstore_handlers.BlobstoreDownloadHandler
クラスがそれらヘッダを設定するので、通常はあなたが自分で設定する必要はありません。
詳細については Blobを使用するを参照してください。
カスタムHTTP 応答ヘッダは、アプリケーションの設定ファイルにて、動的および静的なURLごとに設定できます。
詳細については 設定ドキュメント にあるhttp_headers
の項目を参照してください。
リクエストハンドラーには、リクエストに対して応答を生成したり返したりする際に時間制限があります。 一般的にはだいたい60秒です。期限を超過すると、リクエストハンドラーは中断されます。
Python ランタイム環境では、google.appengine.runtime
パッケージからDeadlineExceededError
が発生するとリクエストハンドラを中断させます。
リクエストハンドラがこの例外をキャッチできない場合(キャッチできない例外のように)、ランタイム環境はクライアントへHTTP 500サーバエラーを返します。
リクエストハンドラーでは、この例外をキャッチして応答をカスタマイズすることができます。 例外が発生すると、ランタイム環境は応答をカスタマイズするための若干の猶予時間(1秒未満)をリクエストハンドラに与えます。
from google.appengine.runtime import DeadlineExceededError
class MainPage(webapp2.RequestHandler):
def get(self):
try:
# Do stuff...
except DeadlineExceededError:
self.response.clear()
self.response.set_status(500)
self.response.out.write("This operation could not be completed in time...")
猶予期間内にハンドラーが応答を返したり例外を発生させたりしない場合、ハンドラーは終了して既定のエラー応答が返ります。
リクエストが応答を返すまでには60秒の猶予時間がありますが、App Engineはリクエストの生存時間が短いアプリケーション(通常は数百ミリ秒)向けに最適化されています。 効率的なアプリは、ほとんどのリクエストに対して迅速に応答します。 迅速に応答しないアプリは、App Engineのインフラ上で上手く拡張できません。
一般的なDeadlineExceededError の原因と推奨される対処方法についてはDeadlineExceededErrorsに対処するを参照してください。
バックエンドを使用することで、このリクエストタイマーを回避できます。; バックエンドではリクエストの生成や応答について時間制限がありません。
SPDYをサポートしているブラウザがSSL経由でアクセスした場合、App Engineアプリケーションは自動的に SPDY プロトコルを使用します。 これはHTTP の代わりとしてGoogleがデザインしたもので、ウェブページのダウンロードの待ち時間を減らすためのものです。 SPDY を使用しても、アプリケーションとユーザーの両方でそのことを意識する必要はありません(普通のHTTPを使っているかのように、アプリケーションを記述できます)。 詳細情報についてはSPDY プロジェクトのページを参照してください。
App Engine ウェブサーバは、ウェブリクエストへの応答のためにハンドラスクリプトが標準出力ストリームに書き出した全てをキャプチャします。
また、ハンドラスクリプトが標準エラーストリームに書き出した内容も全てキャプチャしてログデータとして保存します。
各リクエストにはrequest_id
が割り当てられます。request_id
はリクエストの開始時間を基に生成された世界で唯一の識別子です。
ログデータは開発者コンソールのログページで閲覧でき、appcfg.py request_logsを使ってダウンロードできます。
App Engine Python ランタイム環境には、Python 標準ライブラリのloggingモジュールの特別サポートが含まれており、ログレベル("debug", "info", "warning", "error", "critical")のようなログ概念を理解することができます。
import logging
from google.appengine.api import users
from google.appengine.ext import ndb
user = users.get_current_user()
if user:
q = ndb.gql("SELECT * FROM UserPrefs WHERE user = :1", user)
results = q.fetch(2)
if len(results) > 1:
logging.error("more than one UserPrefs object for user %s", str(user))
if len(results) == 0:
logging.debug("creating UserPrefs object for user %s", str(user))
userprefs = UserPrefs(user=user)
userprefs.put()
else:
userprefs = results[0]
else:
logging.debug("creating dummy UserPrefs for anonymous user")
実行環境は、自動的にいくつかの環境変数を設定します;app.yaml
ではそれらの他にも環境変数を設定できます。
自動的に設定される変数の中のいくつかは App Engine固有の変数で、その他はWSGI 標準やCGI 標準の変数です。
Python のコード上からはos.environ
ディクショナリを使ってこれらの変数にアクセスできます。
以下の環境変数は App Engine固有のものです:
CURRENT_VERSION_ID
: 現在実行しているアプリケーションのメジャーバージョンとマイナーバージョンを "X.Y"形式で表します。
メジャーバージョンの数字("X")はアプリのapp.yaml
ファイルで設定されます。
マイナーバージョンの数字("Y") は、各バージョンのアプリがApp Engineにアップロードされた時に自動的に設定されます。
開発ウェブサーバでは、マイナーバージョンは常に "1"となります。
AUTH_DOMAIN
: ユーザーAPIでユーザーを認証するのに使われるドメイン。
appspot.com上でホストされているアプリではAUTH_DOMAIN
の値はgmail.com
となり、任意のGoogle accountを使用できます。
Google Appsを使ったカスタムドメイン上でホストされているアプリでは、 AUTH_DOMAIN
はカスタムドメインと同じ値になります。
INSTANCE_ID
: リクエストを処理するフロントエンドインスタンスのインスタンスIDが入っています。
このIDは16進数の文字列型の値です (例えば、00c61b117c7f7fd0ce9e1325a04b8f0df30deaaf
)。
ログインした管理者はURL: http://[INSTANCE_ID].myApp.appspot.com/
内でこのIDを使用できます。
リクエストはURLで指定したフロントエンドインスタンスにルーティングされます。
インスタンスがリクエストを処理できない場合、即座にエラー503が返されます。
以下の環境変数はWSGI 標準と CGI 標準のもので、App Engineでは特殊な動作をします。:
SERVER_SOFTWARE
: 開発ウェブサーバ上では、この値は "Development/X.Y" となり、 "X.Y" はランタイムのバージョンです。
App Engine上で動作する場合は、この値は"Google App Engine/X.Y.Z"となります。
追加の環境変数は、WSGI 標準やCGI 標準に従って設定されます。 これら環境変数の詳細情報については、 適宜 WSGI 標準 や CGI 標準を参照してください。
app.yaml ファイル
にも環境変数を設定できます:
env_variables:
DJANGO_SETTINGS_MODULE: 'myapp.settings'
import os
import webapp2
class PrintEnvironmentHandler(webapp2.RequestHandler):
def get(self):
for name in os.environ.keys():
self.response.out.write("%s = %s<br />
" % (name, os.environ[name]))
リクエスト時には、リクエストに対してユニークに割り振られたリクエストIDを保存できます。
リクエストIDは、後でfetch()
機能のrequest_ids
パラメータとして使い、ログから対象リクエストを探すのに使用できます。
以下のサンプルコードはリクエストのコンテクスト内でリクエストIDを取得する方法になります。:
import os
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('REQUEST_LOG_ID=' +
(os.environ.get('REQUEST_LOG_ID')) + '
')
app = webapp2.WSGIApplication([('/', MainPage)])
スタンドアロン環境のPythonアプリケーションが複数のファイルからモジュールがインポートされても一回しかモジュールを読み込まないのと同様に、
Python ランタイム環境は単一のウェブサーバ上で複数のリクエストでインポートされたモジュールをキャッシュします。
WSGI ハンドラはモジュールなので、リクエストがあるとキャッシュされます。
CGI ハンドラスクリプトの場合は、main()
routineを使用している場合のみキャッシュされます。;使用していないと、 リクエストの度にCGI ハンドラスクリプトが読み込まれます。
WSGI とCGIの違いについての詳細情報はリクエストを参照してください。
アプリのキャッシュ機能によって応答時間に大きなメリットがあります。前述のように、 全てのCGI ハンドラーはスクリプトは main() routineを使用することを推奨します。
効率性のために、ウェブサーバはインポートしたモジュールをメモリ内に保存し、同じサーバの同じアプリケーションに対する後続リクエストの場合は、モジュールの再読み込みや再精査を行いません。 ほとんどのモジュールはインポートされた時にグローバルデータを初期化せず、その他副作用も無いので、モジュールをキャッシュしてもアプリケーションの動作に変化はありません。
リクエストの度に精査されるモジュールに依存しているモジュールをインポートする場合、アプリケーションはこのキャッシュ動作に対応しなければなりません。
以下のサンプルで、インポートされたモジュールがどのようにキャッシュされのかを例示します。
mymodule
は一つのウェブサーバで一回のみインポートされるので、 グローバルの mymodule.counter
値はサーバからの初回リクエストの時に0に初期化されるのみです。後続のリクエストは前回リクエストが使った値を使います。
### mymodule.py
counter = 0
def increment():
global counter
counter += 1
return counter
### myhandler.py
import webapp2
import mymodule
class MyHandler(webapp2.RequestHandler):
def get(self):
self.response.headers["Content-Type"] = "text/plain"
self.response.write("My number: %d" % mymodule.increment())
app = webapp2.WSGIApplication([("/", MyHandler)],
debug=True)
上記は My number: #
という結果を出力します。#
にはこのリクエストを処理するウェブサーバによってこのハンドラが呼び出された回数が入ります。
App Engineに対して、インポートしたモジュールに加えて CGIハンドラスクリプト自身もキャッシュするよう指示することができます。
ハンドラスクリプトでmain()
という名前のfunction を定義した場合、スクリプトとそのグローバル環境はインポートしたモジュールのようにキャッシュされます。
設定したウェブサーバ上でスクリプトに最初のリクエストが発生した場合、通常通りスクリプトの精査が行われます。後続のリクエストが発生した場合、 App Engine はキャッシュされた環境にある main()
function を呼び出します。
ハンドラースクリプトをキャッシュするには、 App Engine が引数を指定せずにmain()
を呼び出せるようにする必要があります。
ハンドラースクリプトが main()
functionを定義していなかったり、main()
functionに引数が必要な(既定のmain()を実装していない)場合は、
App Engineはリクエストの度にスクリプト全体を読み込んで精査します。
メモリ内に解析済みのPythonコードを維持しておくことで、処理時間が節約でき、より早い応答ができるようになります。Caching the global environment has other potential uses as well:
コンパイルされた正規表現。全ての正規表現は解析されてコンパイルされた形式で保存されます。グローバル変数にコンパイルされた正規表現を保存し、二回目以降のリクエストではアプリのキャッシュ機能を使ってコンパイルされたオブジェクトを再利用することができます。
GqlQuery オブジェクト。GqlQuery オブジェクトが作成された時、 GQL クエリ文字列が解析されます。 bind()メソッドでパラメータが紐付けられているGqlQuery オブジェクトを再利用すると、毎回GqlQuery オブジェクトを再作成するよりも処理が早くなります。 You can store a GqlQuery object with parameter binding for the values in a global variable, then re-use it by binding new parameter values for each request.
ハンドラースクリプトをインポートする時は main()
を呼び出すようにしてください。
App Engineはスクリプトのインポート時にmain()
も呼び出されているものとして処理を行うので、サーバ上で初回のリクエストハンドラの読み込み時にはmain()
の呼び出しを行いません。
以下の例では、スクリプトのグローバル環境のキャッシュを使って、前述のサンプルコートと同じことを行っています。:
### myhandler.py
# A global variable, cached between requests on this web server.
counter = 0
def main():
global counter
counter += 1
print "Content-Type: text/plain"
print ""
print "My number: " + str(counter)
if __name__ == "__main__":
main()
main()
を使ったアプリのキャッシュ機能によってあなたのCGIの応答時間は大きく改善されます。CGIを使っている全てのアプリケーションでこのキャッシュ機能の使用を推奨します。
Google App Engine ではトラフィックの増加に応じてあなたのアプリケーションに自動的にリソースを割り当てます。 しかし、それには以下の制限があります。:
アプリケーションが受信した各リクエストは、リクエスト 制限にカウントされます。 リクエストに対する応答で送信されたデータは送信帯域幅 (課金可能)制限にカウントされます。
HTTPリクエスト とHTTPS (安全な)リクエストは両方とも リクエスト制限と受信帯域幅 (課金可能)制限と 送信帯域幅 (課金可能) 制限にカウントされます。 開発者コンソールの割り当て量の詳細ページでも情報提供のために別の値として セキュアリクエストとセキュア受信帯域幅と セキュア送信帯域幅を報告します。 HTTPSリクエストのみがこれらの値にカウントされます。詳細情報については割り当て量ページを参照してください。
システム全体の安全制限に加えて、以下の制限がリクエストハンドラの使用時に適用されます。:
制限 | 制限値 |
---|---|
リクエストサイズ | 32 メガバイト |
応答サイズ | 32 メガバイト |
リクエスト時間 | 60 秒 |
ファイル(アプリケーションファイルと静的ファイル)の最大数 | 合計10,000 ディレクトリごとに1,000 |
アプリケーションファイルの最大サイズ | 32 メガバイト |
静的ファイルの最大サイズ | 32 メガバイト |
全てのアプリケーションファイルと静的ファイルの最大合計サイズ | 最初の1ギガバイトは無料 それを超えると1ギガバイトあたり月額 $ 0.026 |