GMOアドマーケティングのy.yです。
去年の11月以来、2回目のブログとなります。
今回はGo言語のGoogle App Engine環境移行奮闘記となります。
FlexibleからStandardに移行しようと思った理由はコストを抑えたい!
なぜ、初めからStandardを選択しなかったかというとGo1.9がStandardで対応していなかったからです。
でも2018/03/19からStandardでGo1.9が使えるようになったとリリースノートに書いてありました。(gcpugの方に教えていただきました)
ということで、app.yamlをちょろっと書き換えて2、3時間あれば大丈夫だろうなという
ものすごい気楽な気持ちで環境を切り替えることを心に決めました。
が結果そこから24時間程度かかることになり、頭の中で悪魔と悪魔がささやいていたので
やっぱり切り替えるのやめようかなとも考えましたがなんとか切り替えることができました。
やったこと
- app.yaml変更
- アプリケーションディレクトリ構成変更
- contextの生成方法変更
- アプリケーションロジックをStandard環境用に変更
詳細
1. app.yamlをFlexibleからStandardに変更
変更前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#Flexible runtime: go env: flex service: xxxx automatic_scaling: min_num_instances: 1 max_num_instances: 1 cool_down_period_sec: 180 cpu_utilization: target_utilization: 0.6 resources: cpu: 1 memory_gb: 0.6 disk_size_gb: 10 env_variables: DEPLOYMENT_ENV: production |
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#Standard application: xxxx service: contents-api runtime: go api_version: go1.9 instance_class: F1 automatic_scaling: min_idle_instances: 0 max_idle_instances: automatic # default value min_pending_latency: 30ms # default value max_pending_latency: automatic max_concurrent_requests: 80 env_variables: OAUTH2_CALLBACK: 'https://your-project-id.appspot.com/oauth2callback' DEPLOYMENT_ENV: 'production' handlers: - url: /stylesheets static_dir: stylesheets - url: /(.*\.(gif|png|jpg))$ static_files: static/\1 upload: static/.*\.(gif|png|jpg)$ - url: /.* script: _go_app |
2. gcloud app deployをすると下記のエラーが発生します
1 2 3 |
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed: 2018/03/22 19:17:11 go-app-builder: Failed parsing input: package "github.com/xxxx/xxxx/vendor/go.opencensus.io/trace" cannot import internal package "go.opencensus.io/internal" |
エラーについては下記を参照
https://issuetracker.google.com/issues/38449183
goapp deployの場合はvendorがアプリケーションのルートディレクトリにあれば問題なくdeployできるとの情報ありました。
gcloud app deployでdeployの対応方法としてアプリケーションのディレクトリ構成を変更
参考:https://qiita.com/koki_cheese/items/216fe73caf958db34aa2
参考:https://motemen.hatenablog.com/entry/2016/11/gae-go-building
ディレクトリ構成変更前
1 2 3 4 5 6 7 8 9 10 |
$GOPATH/src/github.com/user/gae-app |-- appengine/ | |-- app/ | | |-- lib/ | |-- lib.go | | |-- app.yaml | | |-- main.go | | ... |-- vendor/ ... |
ディレクトリ構成変更後
1 2 3 4 5 6 7 8 9 10 11 12 |
$GOPATH/src/github.com/user/gae-app |-- appengine/ | |-- app/ | | |-- app.yaml | | |-- main.go | | ... | `-- gopath/ | |-- src/github.com/user/gae-app/lib # lib への symlink| | |-- src/github.com/labstack # vender/github/labstack への symlink |-- lib/ # アプリケーションのコアロジック |-- vendor/ ... |
あとはdeployするときにGOPATHを切り替えてdeploy。deployのたびにGOPATHを切り替えなければいけないのは面倒ですが
1 2 3 4 5 |
$ export GOPATH/src/github.com/user/gae-app/appengine/gopath $ cd GOPATH/src/github.com/user/gae-app/appengine/app $ gcloud app deploy |
その他の対応はdev_appserverでdebugしながら原因調査と対処をしました。
今回ディレクトリ構成の変更以外で対応した箇所は以下になります。
3. internal server errorとなり、debugしていたら認証部分でエラーとなっていたのでcontextの変更
変更前
1 |
ctx := context.Background() |
変更後
1 |
ctx := appengine.NewContext(r) |
4. DefaultClient 使えないとのことなので
1 2 3 |
[ Get https://hogehoge.co.jp/: http.DefaultTransport and http.DefaultClient are not available in App Engine. See https://cloud.google.com/appengine/docs/go/urlfetch/ ] INFO 2018-03-26 09:33:25,095 module.py:835] contents-crawler: "GET /?url=https%3A%2F%2Fhogehoge.co.jp%2F HTTP/1.1" 500 155 |
https://cloud.google.com/appengine/docs/standard/go/issue-requests
変更前
1 |
res, err = http.DefaultClient.Do(req) |
変更後
1 |
client := urlfetch.Client(ctx) |
# リクエストが404になってしまうのでhttp handleでルーティング等の指定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package main import ( "net/http" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "google.golang.org/appengine" ) func main() { // Echo instance e := echo.New() // Middleware e.Use(middleware.Logger()) e.Use(middleware.Recover()) // Routes e.GET("/test", lib.test) http.Handle("/test", e) appengine.Main() } |
まとめ
対応した内容は大したことなかったけど、わからないことがたくさんあったので時間もかなりかかってしまい色々と苦労しました。
でも前回のブログの時よりほんの少しだけど成長できたかなと思います。
前回のブログ
Go言語でGoogle Cloud StorageへのUploadとBigQueryで集計