Google App Egnineには「バージョン」という概念があり、ひとつのアプリケーションに複数のバージョンを同時にデプロイしておくことができます。1 そのうちのひとつが「デフォルトバージョン」となり、そこへユーザがアクセスする仕組みになっています。2
このバージョン機能はアプリケーションのバックアップとして使うこともできて便利です。例えば現在のバージョン「version1」に新機能を追加して「version2」をデプロイしてデフォルトバージョンと設定した。。。が、バグが見つかった…といった場合に、元々稼働していた「version1」をデフォルトバージョンに設定し直せばアプリケーションはこれまで通りになるわけです。
デフォルトバージョンの切り替え方法
新しいバージョンをデプロイした後、管理コンソールからGUIから操作して特定のバージョンをデフォルトバージョンとして設定することもできますし、appcfg
というCUIツールからset_default_version
というコマンドを使ってデフォルトバージョンを切り替えることもできます。なおデフォルトバージョンを設定することを、以降「バージョンの切り替え」と表現します。
デフォルトバージョンを切替えしている瞬間のリクエストはどうなる?
以前のGoogle App Engineでは、デフォルトバージョンを切り返している瞬間にリクエストを投げつけると、時々500エラーを返していた気がするのですが、この記事を書くために試したところ一度もエラーが返されませんでした。バージョン切り替え前後にかなーーり密度濃くリクエストし続けたんだけど、おかしいな。この記事は「スマートなデフォルバージョンの切り替え」を目標にしていたので困りました。まぁいいや、たぶんたまにはエラーが発生するのかもしれません?ということにして進めます。普通に考えると、デプロイしたばかりの新バージョンはインスタンスが存在していないはずで、急に頻度高くリクエストを受けても捌き切れないのはなんとなく理解できますね(この記事的には捌き切られてしまうとエラーにならず困りますが)。
そういう時のための対策がいくつかあります。
スマートにバージョンを切り替えるには?
warmup
特定のバージョンを狙ってリクエストを投げることもできるので、切り替え先のバージョンにリクエストを仕込んでおいて、インスタンスが増えるを待ちます。インスタンスが増えてきたところでバージョンを切り替えます。
Traffic splitting
いきなりバージョンを切り替えるのではなく、リクエストの一部を別のバージョンに振り分ける機能です。切り替えたいバージョンに何%のリクエストを振り分けるかを設定できます。こちらも、インスタンスが増えてきたところでバージョンを切り替えます。
Traffic migration
上記の「Traffic splitting」+「バージョン切り替え」を自動で行ってくれる機能です。。。と単純に考えていましたが、上記の場合は切り替え先のバージョンに対して、「管理者かユーザが」リクエストを送ることになるのですが、Traffic migration機能の場合は「Google App Engineが内部的に」warmupのためのリクエストを送り、確実にインスタンスを増やしてからバージョン切り替えをしてくれるようです。ユーザの利用状況も気にする必要が無くなかなか賢いです。
Traffic migrationが実行中の間は、バージョンの状態が default = YES|NO ではなく、切り替え元と切り替え先に「Traffic Source|Traffic Destination」となります。また、バージョン切替中はTraffic splittingの機能も同時に設定されます。
先ほど試したところ、33インスタンス起動しているバージョンから外部からのリクエストを一切遮断したままTraffic migrationを実行した場合、切り替え先のバージョンに19インスタンス立ち上がった後にバージョン切り替えが行われました。どのタイミングで切り替え完了とみなすのかは不明ですが、内部的なリクエストだけでもそこそこのインスタンスを立ち上げてくれるようです。
Traffic migrationを実行する手順も簡単で、管理コンソールのバージョン一覧画面からGUIで実施することもできますし、appcfg
というCUIツールからmigrate_traffic
というコマンドを使うこともできます。3
appcfg.sh --oauth2 -A $APPID -M $MODULE -V $VERSION migrate_traffic $APPDIR
まとめ
便利な機能だと思うので、今後は set_default_version
で切り替えるのではなく migrate_traffic
でバージョン切り替えを行うようにしましょう。
-
実際には、Module ごと Version ごとにアプリケーションをデプロイできるため、Module数 * Version数のアプリケーションをデプロイできることになります。 ↩
-
https://{version}-dot-{applicationId}.appspot.com のように、特定のバージョンのアプリケーションにアクセスすることもできます。 ↩
-
Python版の
appcfg.py
ではなくappcfg.sh
のhelpを見ると、migrate_traffic
がコマンドとして表示されませんし、リファレンスでJava用の表示にしてにもappcfg.py
しか書かれていませんが、実際には使用できます。 ↩