Modules のリクエストルーティング, TaskQueue のTask 実行モジュールとバージョンについて (2015.06)
リクエストのルーティングについて:
https://cloud.google.com/appengine/docs/python/modules/routing
- URLによるモジュール・バージョン(・インスタンス)指定
- URL で module, version (, instance) を指定できる.
- URL に module, version (, instance) を併記した指定は、dispatch.yaml の指定より優先される.
-
These two address forms are guaranteed to reach their target (if it exists). They will never be intercepted and rerouted by a pattern in the dispatch file:
https://instance-dot-version-dot-module-dot-app-id.appspot.com
https://version-dot-module-dot-app-id.appspot.com
-
- dispatch.yaml による指定
- dispatch.yaml を設置して、特定のホストやパスに対するリクエストを指定したモジュールに転送できる.
- 1 file/application, max 10 routing rules
- https://cloud.google.com/appengine/docs/python/modules/routing#routing_with_a_dispatch_file
- デフォルト
- URLでモジュール(or バージョン)だけ指定する・または指定しない.
- dispatch.yaml に設定があればそちらのほうが優先される。
-
These address forms have a default routing behavior. Note that the default routing is overridden if there is a matching pattern in the dispatch file:
-
https://module-dot-app-id.appspot.com
https://version-dot-app-id.appspot.com
https://app-id.appspot.com
- URL指定も設定もなければ default module の default version で実行される.
http://app-id.appspot.com/path
指定した module や version が存在しない場合は、デフォルトにフォールバックする(Not Found にはならない).
TaskQueue (Push), Cron についてはそれぞれの yaml で target: を書いておくことができる。これを使って処理の種類によって実行 module をわけるということができる。(重たい画像処理をスペックの高いインスタンスで実行など)
- https://cloud.google.com/appengine/docs/python/config/queue
- https://cloud.google.com/appengine/docs/python/config/cron
queue.yaml, cron.yaml による指定:
- queue毎、cron job毎に target を指定できる(
target: "mymodule"
). target はmodule
,version
,version.module
のいずれかの値を取る. - 指定した target が prepend されたホストに対してリクエストが送信される.
-
The string is prepended to the domain name of your app when constructing the HTTP request for a task.
http://target.app-id.appspot.com
-
- target に
version.module
と指定した場合も、target を prepend したホストに対してリクエストが送られる.http://version.module.app-id.appspot.com
Task.target:
- Task を enqueue する際に target を動的に指定できる。
taskqueue.add(target="...")
,Task(target="...")
など- ただし、queue.yaml に指定がある場合はこの引数は無視される。
- https://cloud.google.com/appengine/docs/python/taskqueue/tasks#task_target
-
The target argument is ignored and has no effect if your queue.yaml file also sets a target for the queue.
target の指定が全くされていない場合は、Task を add した際のURL(module/version)が引き継がれる.
If target is unspecified, then tasks are invoked on the same version of the application where they were enqueued.
(https://cloud.google.com/appengine/docs/python/config/queue#target)
URLもデフォルトの場合は (Task実行時点での) default version で実行される.
Note that if the default application version changes between the time that the task is enqueued and the time that it executes, then the task will run in the new default version. (https://cloud.google.com/appengine/docs/python/config/queue#target)
appengine-pipelines では pipelineのワークフロー全体をつうじて start時のversion, module が引き継がれるつくりになっている模様.
Introspectively set the target so pipelines stick to the version it started. (https://github.com/GoogleCloudPlatform/appengine-pipelines/blob/master/python/src/pipeline/pipeline.py#L469-L471)
dispatch.yaml はリクエスト受信時のルーティングの設定だが、 TaskQueue, Cron の target はリクエストの送信先(どのホストにリクエストを送るか)を決める設定であり、処理のフェーズや実質が異なる.
queue.yaml と dispatch.yaml の指定がバッティングする場合, dispatch の方が優先される.
Note: If you are using modules along with a dispatch file, your task's HTTP request may be intercepted and re-routed to another module. (https://cloud.google.com/appengine/docs/python/config/queue#target)
ただし、これは target 指定した queue の taskが http://target.app-id.appspot.com/path-to-task
にリクエストされるため. このURL形式については上記の通り dispatch.yaml の指定が優先して適用される.
従って、queue.yaml の target に target: "version.module"
とバージョン含めた指定をすると、リクエストURLが http://version.module.app-id.appspot.com/path-to-task
となり、指定した通りの module / version で実行される.
タスクがどのURLでリクエストされ、どのモジュール・バージョンで実行されるかのまとめ.
target.myapp.appspot.com
から enqueue した Task は...- ->
Task(target="target")
となる- IF: queue に
target: mymodule2
と指定されている- ->
mymodule2.myapp.appspot.com
にリクエスト- -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
- ->
- IF: queue に target 指定がない
- ->
target.myapp.appspot.com
にリクエスト- -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
- ->
- IF: queue に
- ->
myversion.mymodule.myapp.appspot.com
から enqueue した Task は...- ->
Task(target="myversion.mymodule")
となる- IF: queue に
target: "mymodule2"
と指定されている- ->
mymodule2.myapp.appspot.com
にリクエスト- -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
- ->
- IF: queue に target 指定がない
- ->
myversion.mymodule.myapp.appspot.com
にリクエスト- -> myversion.mymodule で実行される
- ->
- IF: queue に
- ->
myapp.appspot.com
から enqueue した Task は...- ->
Task(target=taskqueue.DEFAULT_APP_VERSION)
- IF: queue に target 指定がある
- -> 同上
- IF: queue に指定がない
- -> デフォルトルーティングに従って処理される (dispatch があれば優先される)
- IF: queue に target 指定がある
- ->
- queue.yaml の target 指定
- Pros
- queue ごと = 処理の種類ごとに Module を変えられる柔軟性がある
- プログラムコードの変更なしでモジュールを変更できる(TaskQueue 利用箇所で queue をこまめに指定している前提)
- Cons
- Task追加時の暗黙のversion引き継ぎも無効になるので、defaultバージョン (or queueで指定したバージョン) 固定に(ほぼ)なる. 1 application 内で複数の version を運用する(開発や検証用の環境など) のには向かない.
- Pros
- dispatch.yaml
- Pros
- URL単位で Module を切り替えられるので手軽
- プログラムの変更なしでモジュールを変更できる (URLがきれいに分割されている前提)
- Cons
- deferred, mapreduce, pipeline など、同じ URL で多様な処理をするものの扱いに困る
- 単純な glob しか指定できないので、複雑な構成は作れない (-> Pros?)
- ... が、max 10 rules という制限があるのでむやみにつかえない
- Pros