Betaが公開されたので早速触ってみたのでサラッと書いてみた
go1.9ランタイムからgo1.11ランタイム(2nd gen)に移行するためには最低限やることと気をつけること
中身的には このへん の内容です。
app.yamlで go111
ランタイムを指定する
今までは多分 api_version
で指定していたと思いますが、 api_version
は Deprecated になります。
そのため、 runtime
へ指定します。
また、以下のタグも同様に Deprecated になります
- application_readable
- builtins
- login
- libraries
- threadsafe
- skip_files
Deprecatedのフィールドを利用している場合、deploy時にエラーになるようです。
サービス単位でmainパッケージが必要
旧世代のランタイムだとinitで初期化できていましたが、今後はmainパッケージが必要になります。
appengine ビルドタグが廃止されます
なんだっけ?これ。
追記 2018/10/16
// +build !appengine
みたいなやつですね。
GoのBuild Constraintsという仕組みを利用しており、こちら に説明があります。
appengineの場合はtenntennさんからコメントで頂いているように、unsafeパッケージなどをライブラリで利用していた場合にappengineでは利用できないため指定されている場合などがあったようです。
実際、unsafeが利用できるようになったので以下のようなコードをappengineにデプロイすることができました。
byteをStringにする際に最速の変換方法です。
b := []byte("ハローワールド")
w := *(*string)(unsafe.Pointer(&b)) // []byte -> string
fmt.Println(w) // ハローワールド
依存関係をプロジェクトに取り込む方法が変わって以下の2パターン
- アプリケーションのコードと依存関係をGOPATHに配置する
- go.modファイルを利用して定義する
Appengine固有のAPIではなく、Google Cloudクライアントライブラリを使って!
GAE/FEやGKEと同様にGoogleCloudクライアントライブラリを利用する必要があります。
このへん にまとまっています。
TQ、Datastore、AppengineMemcacheなどを利用していた方はもれなく移行が必要です。
appengineパッケージが必要な場合には、google.golang.org/appengineパッケージが利用できます。
追記 2018/10/16
Appengine SDKからCloud SDKに絶対移行する必要がある。という感じで書いてしまっていましたが、訂正です。
- CloudSDKへの移行は
strongly recommend
であって必須ではありません。 - google.golang.org/appengineパッケージ(Appengine SDK)を引き続き利用できますが、その際にはmainパッケージで
appengine.Main()
を実行する必要があります。- appengine.Main内で
internal.Main()
を呼んでおり、内部でhttp.ListenAndServe
を行っているので、main内に自分で実装する必要はありません。(下にMainの実装など書いていますが。)
- appengine.Main内で
apstndbさんご指摘ありがとうございます。
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()
を呼んでも問題なく動いているように見えます(推奨されるのか不明だけど)
追記 2018/10/16
上で書いたように、Appengine SDKを利用する場合には 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と同じ記述で指定できる)
サラッと触ってみた結果はこんな感じ。
改めてもう少し触ってみて記事を書こうと思う