はじめに
Google App Engine(GAE)を使って、バッチ処理が実行できたのでメモです。
GAEではcron.yaml
に設定を記載することで時間を指定した処理を行うことができます。
サンプル
今回は、slackにメッセージを送信するアプリを定期的に実行させてみます。
slackにメッセージを送る部分は以下のサイトに詳しく記載されているので省略します。
CrossBridge Lab | GolangでSlackの特定のチャンネルにメッセージを送る
今回はGAE上でGolangを動かしてみましたよの構成を元に、GAEのプロジェクトを構築します。
ルートディレクトリ(app.yaml
と同じ階層)にcrom.yaml
を作成します。
cron.yaml
cron.yaml
には、以下のように開始時刻や間隔で実行するタイミングを指定することが出来ます。
cron:
- description: "毎朝7時(日本時間)に実行"
url: /morning
timezone: Asia/Tokyo
schedule: every day 7:00
- description: "毎週日曜8時(日本時間)に実行"
url: /morning
timezone: Asia/Tokyo
schedule: every sunday 8:00
- description: "毎日0時を起点とし、1時間単位で実行"
url: /morning
timezone: Asia/Tokyo
schedule: every 1 hours
その他のスケジュール指定方法や、HTTPリクエスト失敗時のリトライ回数は公式のドキュメントに詳しく記載されています。
注意点
GAEではdev_server.py
でローカルにサーバを立ち上げて、動作確認をすることができます。しかし、ローカル環境では、cron.yaml
は動作しません。localhost:8000
からGAEローカル環境の管理画面を開くことができます。
管理画面にcron.yaml
で設定したスケジュールが一覧で表示されるので、Run now
をクリックすることで手動で実行することができます。
Cronの設定を本番環境にデプロイするときは、gcloud app deploy cron.yaml
のようにcrom.yaml
を指定します。
指定しないと、crom.yaml
が読み込まれないため、いつまで待っても処理が実行されません。
Cronが設定されているかどうかは、コンソール画面のcronジョブ
から確認することが出来ます。
仮に他のユーザからHTTPでのリクエストがあった場合、想定していない時間に処理が実行される可能性があります。
そのため、GAEのcronサービスからのHTTPアクセス以外からのアクセスは除外する必要があります。
GAEのcronサービスからのHTTPアクセスにはHTTPヘッダにX-Appengine-Cron: true
が含まれているので、HTTPリクエストを受け取ったタイミングで、チェックする必要があります
例えば、GolangでGAEのcronサービス以外からのHTTPリクエストを弾くには、以下のように書きます。
(弾いた後の処理がお粗末ですが…)
// cron以外からのアクセスは弾く
if r.Header.Get("X-Appengine-Cron") != "true" {
os.Exit(1)
}
感想
GAEはhttp(s)でのリクエストに対してレスポンスを返すだけのサービスだと思っていたので、時間指定で処理を実行してくれるのはとても意外でした。
タイミングをevery monday 09:00
やschedule: 1,8,15,22 of month 09:00
のように指定するのはわかりやすくていいですね。
個人的には、crontabの分 時 日 月 曜日
でタイミングを指定する方法よりは、直感的に感じました。
今回のサンプルファイルはgithubで公開してます。
https://github.com/foresukecom/gae_cron
その他
迂闊先生(@ukkariukatu)の「のみじょし」5巻が出てました!これは買わないと。
紙の本と同じタイミングでKindle版も発売されるのはありがたい限りです😆
…先日までみっちゃんと同い年だったんですが、いつの間にか僕の方が年上になってました。