お題
GAE(Google App Engine)を理解するために、実際に自分でアプリ作って乗せてみる。
Java版の方は仕事で使ったので少しはわかってきた。(さわりレベルだけど)いくつか記事も書いた。
今後はGolang版で試してみる。
まずは、お決まりのクイックスタートを試してみる。
開発環境
# OS
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
# Golang
$ go version
go version go1.9.7 linux/amd64
バージョンの切り替えはgoenvで行っている。
# gcloud
$ gcloud version
Google Cloud SDK 224.0.0
前提
- スタンダード環境での開発とする。
- GCPプロジェクトは作成済み。
- gcloudコマンドインストール済み。
実践
手順は↓に従いつつ、つど、関係するファイルの中身を確認していく。
https://cloud.google.com/appengine/docs/standard/go/quickstart?hl=ja
■サンプルプロジェクト取得
手順通り。
$ go get -u -d github.com/GoogleCloudPlatform/golang-samples/appengine/helloworld/...
$
$ ll golang-samples/appengine/helloworld/
合計 16K
-rw-r--r-- 1 koge koge 69 11月 12 02:51 app.yaml
-rw-r--r-- 1 koge koge 391 11月 12 02:51 hello.go
hello.go
package main
import (
"fmt"
"net/http"
"google.golang.org/appengine"
)
func main() {
http.HandleFunc("/", handle)
appengine.Main()
}
func handle(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, world!")
}
http
パッケージを使って、「/
」アクセス時の挙動を定義するのはGolangでWebアプリ作成する上で基本。
通常は、そのあと、「http.ListenAndServe(":8080", nil)
」として指定ポートで待ち受けるサーバ起動ロジックを書くのだけど、代わりに「appengine.Main()
」と書く。
(まあ、内部でラップしてるんだろうな)
一応、確認。
func Main() {
internal.Main()
}
func Main() {
installHealthChecker(http.DefaultServeMux)
port := "8080"
if s := os.Getenv("PORT"); s != "" {
port = s
}
host := ""
if IsDevAppServer() {
host = "127.0.0.1"
}
if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
log.Fatalf("http.ListenAndServe: %v", err)
}
}
func installHealthChecker(mux *http.ServeMux) {
// If no health check handler has been installed by this point, add a trivial one.
const healthPath = "/_ah/health"
hreq := &http.Request{
Method: "GET",
URL: &url.URL{
Path: healthPath,
},
}
if _, pat := mux.Handler(hreq); pat != healthPath {
mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "ok")
})
}
}
うん、やっぱり。
ヘルスチェックの口(AppEngineでは、なぜか「/_ah/
」というパスから始まる)を追加して、(環境変数でホストとポート指定があれば採用しつつ、サーバ起動するようになってる。
app.yaml
App Engineの挙動を決める設定ファイル。
どういう要素を定義するかは↓に記載してある。
https://cloud.google.com/appengine/docs/standard/go/config/appref?hl=ja
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
クイックスタート用のapp.yaml
では必要最低限の定義がしてある。
要素 | 説明 | 備考 |
---|---|---|
runtime | GAEアプリを動かすための実行環境を指定する。 | 必須要素 |
api_version |
runtime のAPIのバージョン。go1 を指定すると、アプリデプロイのたびに最新のサポートされている実行時環境が使用される(現在go1.9 )。明示的にするなら go1.9 と書く。 |
必須要素 |
handlers | URLパターンのリストとそれらの処理方法の説明。 GAEは、アプリコードの実行、ないし、静的ファイルのホスティングによって、指定のURLアクセス時の挙動を制御できる。 |
必須要素 |
handlers/url | どのパスにアクセスした時にハンドリング処理を発動するか。 |
handlers 指定時は必須要素 |
handlers/script | GAEアプリルートからのスクリプトのパスを指定する。 ただし、Goアプリの場合は常に _go_app にする必要がある。 |
任意要素 |
■ローカル起動
ローカルで起動する時は、起動スクリプトがPythonみたい。
$ dev_appserver.py app.yaml
INFO 2018-11-11 19:03:00,371 devappserver2.py:224] Using Cloud Datastore Emulator.
We are gradually rolling out the emulator as the default datastore implementation of dev_appserver.
〜〜〜
INFO 2018-11-11 19:03:02,127 dispatcher.py:256] Starting module "default" running at: http://localhost:8080
INFO 2018-11-11 19:03:02,129 admin_server.py:152] Starting admin server at: http://localhost:8000
INFO 2018-11-11 19:03:04,904 instance.py:294] Instance PID: 11917
■デプロイ
※当然、「gcloud init
」や「gcloud auth login
」は済んでいる前提。
$ gcloud app deploy
Services to deploy:
descriptor: [/work/src/golang/src/github.com/GoogleCloudPlatform/golang-samples/appengine/helloworld/app.yaml]
source: [/work/src/golang/src/github.com/GoogleCloudPlatform/golang-samples/appengine/helloworld]
target project: [【プロジェクトID】]
target service: [default]
target version: [20181112t042229]
target url: [https://【プロジェクトID】.appspot.com]
Do you want to continue (Y/n)? y
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 87 files to Google Cloud Storage ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://【プロジェクトID】.appspot.com]
You can stream logs from the command line by running:
$ gcloud app logs tail -s default
To view your application in the web browser run:
$ gcloud app browse
GCPコンソール上でも、ランタイム「go」のインスタンスがデプロイされていることを確認。
まとめ
GAEを使うと、用意したアプリをGCPに乗っけるまでが早い。
過去にGKE+goの組み合わせはやったことがあるけど、GAEの制約に乗っかることで、どのくらい楽になったり、融通の効かなさに嫌になったりするのか、いろいろ試してみよう。