えいのうにっき

a-knowの日記です

appengine standard v1 (generation 1) から v2 に移行するためにやったこと

先日、以下のようなメールが Google Cloud から来ており。

Hello 大輔,

We are writing to let you know that we have introduced a lifecycle policy for language runtimes on App Engine Standard, generations 1 and 2 .

## What do I need to know?
The lifecycle policy for language runtimes on App Engine Standard will provide you with information on the duration of support for runtimes and what to expect when a runtime reaches End of Support. Please be advised there is no immediate impact to your current workloads. However, we recommend reviewing the policy as there may be implications if your workload is using an End of Support language runtime.

## What do I need to do?
Review the lifecycle policy and support schedule for the language runtimes in App Engine Standard Generations 1 and 2. We advise you to make plans to migrate your application to a newer runtime if your application’s current runtime is approaching an End of Support date e.g. Python 2.7, Java 8, PHP 5.5

For Gen 1 customers who require additional time to perform their migration, Google may permit your Organization to re-enable deployments in End of Support runtimes, subject to service specific terms and conditions.

片手間の趣味活動で appengine を触っている身としては、appengine standard と legacy の線引きは非常にややこしく、かつポリシーが流動的(であった時期があった?)で、本当に雰囲気でしか把握できていなかったのだけど、その把握していた内容としては以下のとおり。対応するドキュメントとしては多分 App Engine standard environment runtimes  |  Google App Engine standard environment docs  |  Google Cloud このあたり。間違ったこと書いてたらすみません!

  • go111 (Go 1.11) 未満の runtime だと appengine standard legacy。
  • go111 runtime だと appengine standard v1。legacy な API も使える。
  • go112 (Go 1.12) 以上の runtime だと appengine standard v2 になる。
    • 当初は legacy な API はサポートしていなかった・しないというポリシーだった(っけ?)
    • でもこれだと一向にユーザーの移行が進まないことに業を煮やしたのか、一部を除く legacy API(Search とか Mail とか Use login とか? login はいけるのかな?)のサポートも順次されはじめた

上記のような理解だったので、僕の管理している appengine アプリケーションは基本 go111 で運用していた。のだけど、今回上記のようなメールを受け取ったことをきっかけに「そういや、v2 での legacy API サポートの範囲って広がりきったのかな?」と思って Package google.golang.org/appengine/v2 (v2.0.2)  |  Google App Engine standard environment docs  |  Google Cloud のあたりを見てみたところ、気になってた以下のようなあたりも今ではサポートされていそうなことがわかった。

  • delay
  • memcache
  • taskqueue
  • aetest

これはワンチャンあるのでは?と思い、自分が管理している appengine アプリケーションの中でも一番大きい Pixela https://pixe.la の移行作業をやってみたところ、比較的すんなりできた。今回はその記録を残しておこうと思う。

移行前の状況

  • google.golang.org/appengine を使っている
  • go.mercari.io/datastore を使っている
  • github.com/favclip/testerator を使っている
  • github.com/go-chi/chi を使っている

やったこと

1. app.yaml を編集する

app_engine_apis: true は、これまで appengine のサービスとしてバンドルされていたAPI(この表現に自信はない)を引き続き使いたいなら、指定が必要になる( Go 1.12+ 用の以前のバンドル サービスにアクセスする  |  Google App Engine スタンダード環境のドキュメント  |  Google Cloud )。その他、僕は関係なかったけど、以下のような指定も場合によっては必要みたい。( Go 1.11 と Go 1.12 以降の違い  |  Google App Engine スタンダード環境のドキュメント  |  Google Cloud より。)

  • login
    • 以前までの方法でユーザー認証を行う場合。
  • main
    • app.yaml と違う階層に main パッケージを置いている場合に指定が必要。

2. go get google.golang.org/appengine/v2 する

する。

3. google.golang.org/appengine の代わりに 2. で go get したパッケージを使うように変更する

例えば以下のようなかんじに。

  • google.golang.org/appenginegoogle.golang.org/appengine/v2
  • google.golang.org/appengine/loggoogle.golang.org/appengine/v2/log
  • google.golang.org/appengine/memcachegoogle.golang.org/appengine/v2/memcache

4. go get go.mercari.io/datastore/v2 go get go.mercari.io/datastore/v2/aedatastore する

する。

5. go.mercari.io/datastore の代わりに 4. で go get したパッケージを使うように変更する

例えば以下のようなかんじに。

  • go.mercari.io/datastorego.mercari.io/datastore/v2
  • go.mercari.io/datastore/aedatastorego.mercari.io/datastore/v2/aedatastore

あとこれは細かいけど、もし今まで import "go.mercari.io/datastore" とだけしてた場合には import datastore "go.mercari.io/datastore/v2" とすれば変更箇所は最低限にできそう。

6. go get github.com/favclip/testerator/v3 する

する。

7. github.com/favclip/testerator の代わりに 6. で go get したパッケージを使うように変更する

例えば以下のようなかんじに。

  • github.com/favclip/testeratorgithub.com/favclip/testerator/v3

これも細かいけど、今まで import "github.com/favclip/testerator" とだけしてた場合には import testerator "github.com/favclip/testerator/v3" とすれば変更箇所は最低限にできそう。

以上!

なんとこれだけ。念のため、ユニットテストだけでなくE2E的なテストもいい感じに実施したんだけど、特に問題は出なかった。ルーティング周りも、chi を使ってる限りでは特別何かをする必要はなさそうだった。

その他に気になることとしては、今回 runtime と v2 API を使うようになったことによるリソース使用状況の変化について。Pixela の appengine アプリケーションは以前より Mackerel でモニタリングしているのだけど、以下のように、グラフを見る限りでは顕著な差は見られなかった(ピンク矢印のところが v1 → v2 のタイミング)。

これでようやく Go 1.11 なんていう化石みたいな言語バージョンから、Go 1.18 というある程度許されそうな言語バージョンにアップグレードすることができた。だいぶ重い腰ではあったんだけど、やってよかった。

でもよくわかんないのが、v1 と v2 のサポート期限はいっしょっぽいところ( Runtime support schedule  |  Google App Engine standard environment docs  |  Google Cloud )。Googleさん的には、レガシーなAPIをサポートする、となった以上は、v1 か v2 かというところよりも、それを動かす OS と runtime バージョンのほうが matter ってことなのかなぁ。あとは、v1 に対してサポート期限を明示的に示せるようになった(そしてゆくゆくは deprecated にもできるようになった)、というのが大きいか。