DMM.comの、一番深くておもしろいトコロ。

GAE/Go 1.9ランタイムバージョンアップ対応

GAE/Go 1.9ランタイムバージョンアップ対応

  • このエントリーをはてなブックマークに追加

はじめに

みなさんこんにちは、プラットフォーム事業本部 不正対策チームの三浦(@_Andrew_Haru)です。

2019年4月からエンジニア職に転向し、会社ではエンジニア、家では子育てパパとして奮闘中です。
育児休暇の記事はこちらです。

今回は、そんな私が対応したコトについて書いていこうと思います。

何があった

私のチームでは、Google App Engine Standard Environment(GAE SE)/Goで開発しています。Go1.9ランタイムでした。
しかし先日、GCPからGo1.9ランタイムのデプロイに対するサポートの終了告知が出たため、バージョンアップ対応を行いました。

画像

対応内容

GAEではGo1.11またはGo1.12も提供されており、弊チームでは以下の理由でひとまずGo1.11にバージョン上げすることにしました。

  • 開発リソースの都合上、着手時期が遅めではあったので、ひとまず期日までにバージョン上げしてデプロイできるようにしておきたい
  • Datastoreを利用する際にAppEngine固有のAPIを使っており、Go1.12だとそのAPIが利用できない

対応としては主に以下になります。

▼app.yaml ファイルの変更

app.yaml 構成ファイルの一部の要素が非推奨になっているので、利用しないようにします。
弊チームでは api_versionthreadsafeskip_filesを利用しないようにしました。

そして、 runtime:go111 を指定することでGo1.11ランタイムバージョンを利用できるようになります。
また script: _go_appscript: auto にしないとデプロイ時エラーになるので、変更しました。

以下が変更後のyamlファイルになります。

    runtime: go111
    service: service-name
     
    handlers:
        -   url: /.*
            script: auto

▼Working directoryの位置合わせ

Go1.11ではWorking directoryが go.mod の位置になり、localでは app.yamlの位置なので合わせる必要があります。
なので、app.yamlファイルをリポジトリのトップに移動することでデプロイできるようになります。

上記対応では、GCPが1.9から1.11へバージョンアップする際の方法をドキュメントとしてまとめてくれているので、それを参考にしました。

"Migrating your App Engine app from Go 1.9 to Go 1.11"
https://cloud.google.com/appengine/docs/standard/go111/go-differences

▼パッケージ管理を「dep」から「Go Modules」へ移行

Go1.11からはGoModulesというバージョニングシステムが導入されています。
今回の対応に伴い、ライブラリのバージョンも上げる必要があり、そのバージョンがGoModulesにしかサポートされていなかったため、パッケージ管理をGoModulesに変更することにしました。

GAE1.11では、GOPATH modeとmodule-aware modeという2つのモードがあり、どちらかを選択できます。
各ローカルでGOPATHを参照されると動かないので、module-aware modeを有効にしています。

mode 説明
GOPATH mode(Go1.9での管理) ・標準pkg以外を全部 GOPATH 以下のディレクトリで管理
・パッケージの管理はリポジトリの最新リビジョンのみが対象
・パッケージの管理はリポジトリの最新リビジョンのみが対象
module-aware mode(Go1.11での管理) ・標準pkg以外の全てのパッケージをモジュールとして管理
・モジュールの管理やビルドが任意のディレクトリで可能
・モジュールはリポジトリのバージョンタグまたはリビジョンごとに管理される

モードはGO111MODULEという環境変数で切り替えることができます。

▼GAEでのカナリアリリース

今回のバージョン上げに伴うGAEアプリケーションの影響はほぼないという想定でしたが、本番環境で予想外のエラーが急増すると怖いので、
GAEのトラフィックマイグレーションを利用してGo1.11ランタイムバージョンへのカナリアリリースを行いました。

まず、アプリケーションをGAEにデプロイ時、トラフィックが割り当てられないようにオプション --no-promote を指定します。

    gcloud app deploy --no-promote

GAEコンソールから[トラフィックを分割]を選択してGo1.11ランタイムバージョンへのトラフィック量を指定します。

画像

保存すると、GAEが設定したトラフィック量に応じて各バージョンに振ってくれます。

画像

そして、Stackdriver Loggingでエラーログが吐かれていないか、Stackdriver Traceで深刻な性能劣化が見られないかなどを確認していきます。
特に問題がなければ、少しづつGo1.11ランタイムバージョンへのトラフィック量を増やしていく流れです。

さいごに

無事にバージョンアップが完了し、デプロイできる状態になったので一安心です。
引き続き価値あるプロダクトを提供していけるよう頑張ります。

なお、DMMではGCP実弾演習場というサポート制度があります(※AWS実弾演習場のGCP版です)。
業務内容に関係なく、気になったGCPサービスなどを気軽に触ってみることができるので重宝しています。

DMM.comでは一緒に働いてくれる仲間を募集しています。ご興味のある方はぜひ下記募集ページをご確認ください!

https://dmm-corp.com/recruit/