Slide 1

Slide 1 text

Go1.9 で作られた App Engine のサービスを Go1.11 に移行した話 江間啓道 株式会社ディー・エヌ・エー

Slide 2

Slide 2 text

自己紹介 name: 江間啓道 (Hiromichi Ema) twitter: @ema_hiro github: emahiro ServerSide Engineer at DeNA Google AppEngine を使って、マイクロサービスアーキテクチャで作られたプラットフォーム の開発と運用のお仕事でご飯を食っています。 好きな言語は Go です。 好きな PaaS は App Engine です。

Slide 3

Slide 3 text

3 告知

Slide 4

Slide 4 text

4 https://dena.connpass.com/event/128034/ ※ 抽選は5/22なのでもし興味のある方は申込してみてください!

Slide 5

Slide 5 text

5 Go1.9 で作られた App Engine のサービスを Go1.11 に移行した話

Slide 6

Slide 6 text

6 本日お話しすること 1 2 3 まとめ Go1.11 への移行手順 なぜ今から Go1.11 に移行するのか

Slide 7

Slide 7 text

7 なぜ今から Go1.11に移行するのか

Slide 8

Slide 8 text

App Engine で今起きてること ● gVisor 対応(go1.11/go1.12)のランタイムの登場 ○ Googleは今後こちらを推していくと思う ○ go1.9 のランタイムがいつまでサポートされるかわからない ● 新しいランタイムだと今までと同様に App Engine を使うことができない ○ go1.12 以降の App Engine では、appengine パッケージはサポートされないた め、それまで使えていた App Engine 固有機能が使えなくなる 8 App Engine で運用されているサービスには今後影響が出ることが予想される 私たちのチームで運用中のサービスへも影響があることが既に判明している

Slide 9

Slide 9 text

AndApp とは? 9 スマホゲームをPCでできるプラットフォーム ● スマホとPCでアカウントを同期できる。 ● AndAppポイントやツールなどの「捗る」をサポートする便利機能多数。 ● 興味がある方はぜひ -> https://www.andapp.jp にアクセスしてPCアプ リをDLしてみてください。

Slide 10

Slide 10 text

● Microservices on App Engine with Go ● 約 30 個のサービス ● そのほとんどが AppEngine Standard Environment で運用されている 詳細はDeNA TechCon 2018 にて発表された内容を参照してください AndAppにおけるGCP活用事例: https://www.slideshare.net/dena_tech/andappgcp-88366004 AndApp のシステム概要 10

Slide 11

Slide 11 text

● マイクロサービスの各コンポーネントが第1世代 App Engine の固有機能に依存している ● appcfg.py を使用した独自デプロイスクリプト ● 独自のディレクトリ構造をしている ○ direnvでのGOPATHの書き換え ○ 環境ごとのyamlの配置 ○ 独自ディレクトリ構造を前提とした実装 ■ src 配下から conf や andapp-schema を読み込んでいる AndApp の課題 11

Slide 12

Slide 12 text

AndApp における Go1.11 移行モチベーション ● AndApp はApp Engine の固有機能に依存しているので appengine パッケージか ら容易に離れられない ○ Go 1.11 であれば App Engine の固有機能がまだサポートされている ● go1.9 のランタイムがいつまでサポートされるかわからない不安感 ○ 非サポートの期日が決まってから全てを移行する作業はつらい ■ 開発を止める必要がある可能性 => サービスを安心して運用していくために Go1.11 に先んじて移行しておきたい! 12

Slide 13

Slide 13 text

13 Go1.11への移行手順

Slide 14

Slide 14 text

14 1 2 3 AndApp における Go1.11 への移行戦略 Go1.11 へのバージョンアップについて これまでのバージョンアップついて 4 AndApp における Go1.11 への移行手順

Slide 15

Slide 15 text

これまでのバージョンアップについて ● ランタイムの変更はなく、気にしないといけないことはほとんどなかった ○ Go のバージョンアップにおける下位互換についてのみ注意 ● app.yaml で api_version: go1 を指定すると最新のgoのバージョンがデプロイされ る 15

Slide 16

Slide 16 text

Go1.11 へのバージョンアップについて ● プロジェクトのディレクトリ構造に変更がある ○ app.yamlと同階層に main パッケージ の main 関数が必要 ○ GOPATH配下にプロジェクトを設置 ■ direnv で GOPATHを書き換える場合は src をそのまま残す必要がある ■ go.mod 対応する場合は GOPATH/go.mod を配置できないので GOPATH を書き換える設定を外す必要がある 16

Slide 17

Slide 17 text

Go1.11 へのバージョンアップについて ● デプロイコマンドの変更 ○ appcfg.py が非対応に、gcloud app deploy を使う ■ appcfg.py を使いデプロイスクリプトやCDを組んでる場合は影響がある ■ gcloud app deploy に対応した app.yaml の設定項目の変更も必須 ● App Engine の固有機能はサポートされる ○ app.yaml の設定でも go1.9 までは提供していた機能は引き続き利用可能 ● アプリケーションのビルドに Cloud Build が使用される ○ GCP の Cloud Build のコンソールからビルド状況を確認できる ○ Cloud Build への課金必須 17

Slide 18

Slide 18 text

AndApp における Go1.11 への移行戦略 Go1.11 移行のタイミングでやると決めたこと ● 脱 glide && go modules 対応 ○ glide運用のつらみ ● 脱 direnv ○ AndAppでは go modules 対応時に必須 ● gcloud app deploy 対応 ○ 独自デプロイスクリプトをappcfg.py と gcloud app deploy 両対応に 18

Slide 19

Slide 19 text

AndApp における Go1.11 への移行戦略 Go1.11 移行のタイミングでやらないと決めたこと ● go 1.10 以降の機能は使わない (ex. strings.Builder など) ○ ローカルでの起動およびテストには goapp コマンドを使い続けること ■ goapp を使わないと動かない実装が共通ライブラリに存在した ● 脱 appengine package ○ urlfetch => net/http ○ memcache => Memorystore? or Redis Labs? ○ log => standard log or cloud.google.com/logging 19

Slide 20

Slide 20 text

20 AndApp における Go1.11 への移行手順

Slide 21

Slide 21 text

AndAppにおける Go1.11 への移行方法 1. プロジェクトをGOPATH配下に移動 && 脱 direnv 2. glide => go modules への移行 3. main 関数 をプロジェクトのルートに追加 4. app.yaml を gcloud コマンドに対応させる 21

Slide 22

Slide 22 text

プロジェクトをGOPATH配下に移動 && 脱 direnv 22

Slide 23

Slide 23 text

glide => go modules への移行 23

Slide 24

Slide 24 text

main 関数をプロジェクトのルートに追加 24

Slide 25

Slide 25 text

app.yaml を gcloud コマンドに対応させる 25 Element appcfg gcloud app deploy runtime go go111 api_version go1 なし module app なし service なし app handler.script _go_app auto skip_files ex - ^vendor/(.*/)? なし .gcloudignore が必須 main - ex - ./cmd main.go の相対pathを指定で きます。 ex - ./cmd/app - MODULE_NAME/cmd/ app GO111MODULE=onが必須

Slide 26

Slide 26 text

26 Go1.11移行こぼれ話 ~ 移行でハマったところ ~

Slide 27

Slide 27 text

appengine.Main() の内部で呼ばれる関数が異なる 27 ● ビルドタグで internal.Main() を切り替えていた ○ go 1.9 ■ X-AppEngine から始まるリクエストヘッダーを詰め直している ○ go 1.11 ■ リクエストヘッダーの詰め直していない => リクエストヘッダーを取得できるように修正

Slide 28

Slide 28 text

Cloud Build からGitHub Enterpriseにアクセスできない ● DeNA では社内ライブラリを GitHub Enterpriseで管理 ● Cloud Build は go modules 有効なときに、自動で依存関係を解決しようとする => Github Enterprise にアクセスできずデプロイが失敗 28

Slide 29

Slide 29 text

対応 ● GO111MODULE=off && go mod vendor && go.mod をアップロードしない ● Cloud Build でアプリケーションをビルドするときは この vendor を使用 ○ vendor ディレクトリは単体テストを回す時にも参照 29

Slide 30

Slide 30 text

デプロイできないディレクトリ構成がある ● GO111MODULE の on/off ● vendor ディレクトリを設置しての依存関係の解決 をうまく組み合わせないとビルドに失敗してデプロイできない 30

Slide 31

Slide 31 text

デプロイ可 ● GO111MODULE = on 31 ● GO111MODULE = off ● go mod vendor

Slide 32

Slide 32 text

デプロイ可 ~社内ホスティングサーバーを突破する~ ● GO111MODULE = on ● vendor ディレクトリを pkg 配下に追加する ● go modules の replace を使って依存関係を力ずくで解決する (ライブラリのgo.mod対応もセット) 32

Slide 33

Slide 33 text

33

Slide 34

Slide 34 text

34 ↓もしくはこれ↓ postedAt: 05/18/11:53:51 !!! https://daisuzu.hatenablog.com/entry/2019/05/18/115351

Slide 35

Slide 35 text

35 まとめ

Slide 36

Slide 36 text

Go1.12に向けて 36 TODO urlfetch metadataAPIから取得した access_token を使って内部通信判定を行うことで対応可能 memache goon (https://github.com/mjibson/goon) 離脱の検討を進めている。 これ!という代替手段が今のところ見つかっていないことが悩ましい。 log 監視設定の見直しと structured logging を自前で実装する予定 datastore cloud.google.com/go/datastore を使用 トランザクション実装時のシグネチャが 変更になるので対応予定。 taskQueue cloud.google.com/go/cloudtask を使用 CloudTaskではトランザクショナルタスクが非サポート。代替案を検討中。

Slide 37

Slide 37 text

まとめ ● AndApp では先んじで go1.11 に移行し、来たるgo1.12 への移行に備えている ● go1.11 への移行は appengine パッケージからはこのタイミングでは離れない、とい う意思決定をしたので移行は順調に進行中 (実はまだ全て移行できておりません...) ● go1.12 に向けては解決しないといけない課題がある 37

Slide 38

Slide 38 text

38 ご静聴ありがとうございました