Go
GAE
golang
gcp

早速GAE/Go go1.11の次世代ランタイム試してみた

Betaが公開されたので早速触ってみたのでサラッと書いてみた

go1.9ランタイムからgo1.11ランタイム(2nd gen)に移行するためには最低限やることと気をつけること

中身的には このへん の内容です。

app.yamlで go111 ランタイムを指定する

今までは多分 api_version で指定していたと思いますが、 api_versionDeprecated になります。

そのため、 runtime へ指定します。

また、以下のタグも同様に Deprecated になります

  • application_readable
  • builtins
  • login
  • libraries
  • threadsafe
  • skip_files

Deprecatedのフィールドを利用している場合、deploy時にエラーになるようです。

サービス単位でmainパッケージが必要

旧世代のランタイムだとinitで初期化できていましたが、今後はmainパッケージが必要になります。

appengine ビルドタグが廃止されます

なんだっけ?これ。

依存関係をプロジェクトに取り込む方法が変わって以下の2パターン

  • アプリケーションのコードと依存関係をGOPATHに配置する
  • go.modファイルを利用して定義する

Appengine固有のAPIではなく、Google Cloudクライアントライブラリを使って!

GAE/FEやGKEと同様にGoogleCloudクライアントライブラリを利用する必要があります。

このへん にまとまっています。

TQ、Datastore、AppengineMemcacheなどを利用していた方はもれなく移行が必要です。

appengineパッケージが必要な場合には、google.golang.org/appengineパッケージが利用できます。

go1.11ランタイムを利用する場合にはgcloud app deployコマンドを利用する必要があります

goapp コマンドはもう卒業できます。

gcloudコマンドでのデプロイも依存をきれいに解決してくれているように見えるので(vendorなど)もうgcloudで特にトリッキーなgopath設定などしなくても大丈夫なはず。(ちゃんと確認してない)

mainってどうすればいい?

mainのサンプルは ここ にあります。

http.HandleFunc("/", indexHandler)

// [START setting_port]
port := os.Getenv("PORT")
if port == "" {
    port = "8080"
    log.Printf("Defaulting to port %s", port)
}

log.Printf("Listening on port %s", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
// [END setting_port]

こんな感じにすると良いようです。

START-ENDのところを appengine.Main() を呼んでも問題なく動いているように見えます(推奨されるのか不明だけど)

httpハンドラを登録する

ハンドラを登録するには以下のいずれかを利用する必要があります

  • http.HandleFunc()の呼び出しをすべてmainに持ってくる
  • http.HandleFunc()を含むinit関数が起動時に呼び出されるようにパッケージをmainパッケージにインポートする

後者の場合、以下のコマンドが便利

gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#"$gp/src/"} && find . -name "*.go" | xargs grep "http.HandleFunc" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed "s#\./\(.*\)/[^/]\+\.go#\t_ \"$pkg/\1\"#" | sort | uniq

気づいた点

  • ログが旧ランタイムのときのようにリクエストコンテキストでまとまって出力がされなくなっている
    • 現状のFE、GKE、GAE 2nd-gen ランタイム は共通してそのようになっているようなのでしょうがない。
  • uploadしたくないファイルは .gcloudignore ファイルで指定できるっぽい(.gitignoreと同じ記述で指定できる)

サラッと触ってみた結果はこんな感じ。
改めてもう少し触ってみて記事を書こうと思う