APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Datastore Import/Exportの結果をレポートする

先進サービス開発事業部の山岡です。

GCP DatastoreのバックアップにはImport/Exportというサービスを使いますが、これには結果をレポートする機能が無く運用する上で不便です。今回APIをポーリングしSlackにレポートする仕組みを作りましたのでその知見を共有したいと思います。

基本的な動作の流れ

  1. GAE Cronからバックアップのタスクをキックする 参考記事
  2. タスク起動時に取得した name (ジョブ固有に割り当てられるIDのようなもの)を取得しポーリングタスクをキックする( projects/sample-projectname/operations/A1SA0MTEwODhaXNhLXNib2otbmltZGEak0MZAcSMXRzYWwgadGxYWZlVodHJvbi1CjES というような形式です)
  3. APIをポーリングし終了していた場合、もしくは所定の時間内に終わらなかった等の結果をSlackに送信する

結果表示例

f:id:ryo-yamaoka:20180727191601p:plain

シーケンス・フローチャート

f:id:ryo-yamaoka:20180727191421p:plain

f:id:ryo-yamaoka:20180727191326p:plain

サンプルコード

※Slackの通知処理は除外してあります。手前味噌で恐縮ですが、もしよかったら私が作ったライブラリを使ってみて下さい

JSON格納用の構造体とメソッド、変数等

APIからバックアップのタスクを取得する関数

ポーリング処理

注意点

GAEのスケーリング設定がAutomatic Scalingだと1リクエスト60秒制限がありポーリングには使えませんのでBasic Scalingで実行する必要があります。こちらは最大24時間まで処理ができるのでこういった用途に丁度良いでしょう。

Basic Scalingを設定するには

app.yaml を書き換える必要があります。細かい部分を除いた差分としては以下の記述が必要です。

instance_class: B1 # basicとmanualではB系を指定する
basic_scaling:
  max_instances: 3 # 必須。適当な値を
  idle_timeout: 1m # インスタンスがアイドル状態になってから落ちるまでの時間。本件だけの用途なら短くてOK

handlers:
- url: /_ah/start # 起動時処理
  script: _go_app
  login: admin
  auth_fail_action: unauthorized
- url: /_ah/stop # 終了時処理
  script: _go_app
  login: admin
  auth_fail_action: unauthorized

Basic Scalingインスタンスの起動・終了時処理

インスタンスの起動時に所定URLへアクセスが走るので、そのURLの処理を記述しておけば起動処理と終了処理を行うことができます。

起動時は /_ah/start に対しリクエストが来ますが、これに対しHTTP200番代 or 404でレスポンスしないとインスタンスがTerminateされてしまいいつまで経っても処理が始まりません。

また終了時は /_ah/stop にリクエストが来ます。これはどんなレスポンスをしても問題ありませんが、エラー系を返すとログにもエラーで記録されてしまいます。

特に何か処理する必要が無ければ両方ともHTTP204 (No Content)を返却しておけば大丈夫です。Golang+echoでコードを書くとすると以下のような具合になるかと思います。

func init() {
    e := echo.New()

    // basic_scaling起動/停止時のレスポンス
    e.GET("/_ah/start", func(c echo.Context) error { return c.NoContent(204) }) // 起動時にこのURLにリクエストが来る。200番代 or 404でレスポンスしないとTerminateされる
    e.GET("/_ah/stop", func(c echo.Context) error { return c.NoContent(204) })  // 終了時にレスポンスしないとエラーでログが残る(動作的には問題無い)
}