この記事は Brainpad Advent Calender 2019 5日目の記事になります。
大体のサービスの裏には定時実行されるジョブがあるかと思います。
そしてこれらのジョブは並列で動かしたり、途中で失敗したら自動的に再実行するリトライ機構が欲しくなるはずです。
それができないとジョブが完了するまでかなり時間がかかったり、何かが失敗したらそのたびに手動で再実行しないといけなくなります。
そこで非同期タスクの管理が出来るCloud Tasksが役立ちます。
Cloud Tasksとは
まぁこれ見れば全て分かるはずです……。
いつも思うんですけどこういうクラウドサービス特有のポエムを解読するのって初見だと難しくないですか?
もう少しちゃんと説明すると、タスク(HTTPリクエスト)を並列で動かしたり、失敗したら再実行する、というような仕組みをyaml書くだけでできる、というものです。
似たようなサービスとしてPub/Subがありますが、これよりもTasksのほうが細かく設定が可能です。
詳細な比較は以下の通り。
Cloud Tasks か Cloud Pub/Sub かの選択
習うより慣れろ、動かして試してみましょう。
動かしてみる
これの通りやればわかるはずです……。
というともうqiitaの意味ないじゃん、となりますがざっくり流れをいうと以下のような感じです。
- 事前にキュー(タスクを管理する単位)を設定する
- タスク(GAEへのリクエスト)を登録する
- ワーカー(GAEでいうサービス)が動く
- タスクが正常終了(ステータスコード=2xx)したら終わり、そうでなければ再実行
補足
ジョブフローも可能
ワーカー中でタスク登録を行えばタスクをつなげていってジョブフローの管理も可能です。
ただ管理画面からだと現在動いてるタスクの動きしか確認できないため、
グラフで見るとかしたい場合は別のミドルウェアが必要となります。
障害対応しやすい
例えばジョブの途中で事故ったとき。
どのリクエストが失敗したかを確認、コードを修正、アプリをデプロイ、対象のリクエストを手動で再実行する必要があります。
Cloud Tasksだと失敗して留まっているタスクの情報の確認や再実行が管理画面から可能なのでちょっと楽です。
リトライしないという設定も可能
task_retry_limitの設定を0にしておけば、1回だけ実行して失敗したらそのまま放置、というのも可能です。
リトライしなくていいときのAPIのレスポンスを強制的に2xx系にする、というやり方もありますが、これはサービスによるかなと思うので要検討でしょう。
注意点
基本GAE向け
基本的にCloud Tasksは同じプロジェクト内のGAEへのリクエストの管理を行います。
外部へのHTTPリクエストも可能ですが、こちらはベータ版となっています。(2019/12/4現在)
詳しくは以下の通りです。
gcloudコマンド使うよりqueue.yaml使ったほうがよさそう
これはqueue.yamlを適用するとコマンドで設定したキューの設定を上書きしてしまうためです。
チュートリアルだとコマンドで追加してますが、
公式でもコマンドとyaml設定を併用するのは止めようという話をしてます。
ただキューの情報はgcloudのスクリプトよりはqueue.yamlでまとめておいたほうが確認しやすいし、
gcloud app deploy queue.yaml
によるキューの更新が冪等になるのでqueue.yamlのほうが良いかなと思います。
ちなみにqueue.yamlのリファレンスは以下の通り。
python2系とありますが3系でも同様に動かせました。
queue.yamlリファレンス
ローカルでのテストがしにくい
Cloud Tasksにエミュレータはないです。(2019/12/4現在)
したがってやり方としてはGCPの検証環境にデプロイして確認するしかなさそうです。
そのため考えられるのは以下のようなやり方です。
- 事前に検証環境のキュー、ワーカーの設定をしておく
- 開発環境は通常、ローカルのワーカーに対して直接リクエストするような形にする、GCPを経由しない
- CloudTasksの動作確認時のみ、開発環境から検証環境のキュー、ワーカーを指定する
あとはローカルサーバを外部からアクセスできるようにしてワーカーとして指定する、
という方法もあるようですがそこまでやるかどうかは開発者次第です。
Pub/SubもエミュレータできたしいずれはCloud Tasksもできる……かもしれません……。
まとめ
やってみた系ポエム記事になってしまいました。
Web界隈に対して違和感を持たれる可能性が高いので、来年は自作ライブラリ公開したいです。
おわり