cron.yaml を使用したジョブのスケジューリング

App Engine Cron サービスを使用すると、指定した時刻または一定間隔で動作する定期スケジュール タスクを構成できます。このようなタスクは、一般的に cron ジョブと呼ばれています。cron ジョブは App Engine Cron サービスによって自動的にトリガーされます。これを使用して、レポートメールを毎日送信する、キャッシュ データを 10 分ごとに更新する、概要情報を 1 時間に 1 回更新するといったことを実現できます。

cron ジョブは、他の HTTP リクエストと同じ上限を受ける HTTP GET リクエストを使用して、URL を呼び出します。

無料アプリケーションの場合、最大 20 個のタスクのスケジュールを設定できます。有料アプリケーションの場合、最大 250 個のタスクのスケジュールを設定できます。

スケジュールをデプロイまたは更新するには、アカウントに次のいずれかの Identity and Access Management のロールが必要です。

  • オーナー
  • 編集者

Google Cloud コンソールの [IAM] ページで権限を設定できます。

cron 構成ファイルについて

Go 1.11 アプリケーションでのタスクのスケジュールは cron.yaml ファイルを使用して構成します。このファイルは app.yaml と同じく、アプリケーションのルート ディレクトリに存在します。cron.yaml ファイルの例を次に示します。

cron:
- description: "daily summary job"
  url: /tasks/summary
  schedule: every 24 hours
- description: "monday morning mailout"
  url: /mail/weekly
  schedule: every monday 09:00
  timezone: Australia/NSW
- description: "new daily summary job"
  url: /tasks/summary
  schedule: every 24 hours
  target: beta

cron.yaml ファイルには、各 cron ジョブの定義が YAML 構文で記述されています。ジョブ定義には urlschedule が必要です。必要に応じて、descriptiontimezonetarget または retry_parameters を指定することもできます。

url
必須。Cron サービスからのジョブ リクエストの送信先であるアプリの URL です。
schedule
ジョブの実行スケジュールを定義します。後述の構文をご覧ください。
description
省略可。cron ジョブの説明です。Google Cloud コンソールと、ローカル開発用サーバーの管理インターフェースに表示されます。
timezone
省略可。ジョブ スケジュールに使用するタイムゾーンまたは「zoneinfo」の名前を指定します。タイムゾーンを指定しない場合、スケジュールでは UTCGMT とも呼ばれます)が使用されます。
target
省略可。アプリ内の具体的なサービス名を指定します。target が指定された場合、Cron サービスのジョブ リクエストの対象は、アプリ内の当該サービスになります。ジョブ リクエストは、トラフィック用に構成されているサービスのバージョンにルーティングされます。リクエストのルーティング方法をご覧ください。

target に関する重要な考慮事項:

  • トラフィック分割が有効になっていても、ジョブ リクエストの複数バージョンへの振り分けは構成どおりに行われません。
    • IP アドレス分割: Cron サービスからのジョブ リクエストは、常に同じ IP アドレスから送信されるため、毎回同じバージョンにルーティングされます。
    • Cookie 分割: ジョブ リクエストには Cookie が含まれていないため、他のどのバージョンにもルーティングされません。
  • ディスパッチ ファイルを使用する場合、同じ URL が dispatch.yaml でも構成されているとジョブが再ルーティングされることがあります。たとえば、次のとおり /tasks/hello_service2 URL が cron.yaml ファイルと dispatch.yaml ファイルのいずれでも定義されていると、target: service1 が指定されていてもジョブ リクエストは service2 に送信されます。

    cron.yaml:

    cron:
    - description: "test dispatch vs target"
      url: /tasks/hello_service2
      schedule: every 1 mins
      target: service1

    dispatch.yaml:

    dispatch:
    - url: '*/tasks/hello_service2'
      service: service2
retry_parameters
省略可。失敗したジョブの再実行を指定します。後述の構文をご覧ください。

cron ジョブの schedule を定義する

cron ジョブは、一定の間隔で反復するようにスケジュールされ、英語に似た単純な構文で指定されます。スケジュールは、ジョブを 1 日に複数回実行するようにも、特定の月の特定の日付に実行するようにも定義できます。

1 日以内の間隔

反復するスケジュールでジョブを 1 日に複数回実行するには、1 日以内の間隔を使用します。その場合、終了時刻の間隔または開始時刻の間隔を定義できます。

  • 終了時刻の間隔: ジョブの「終了時刻」から次のジョブが開始されるまでの時間を定義します。「終了時刻」とは、ジョブが完了した時刻またはタイムアウトした時刻のことです。この種の間隔の場合、Cron サービスでは、00:00 を起点として 1 日 24 時間を通してジョブが実行され、各ジョブ間は指定された期間だけ待機します。

    例: every 5 minutes というスケジュールの場合、ジョブは毎日 5 分間隔で実行されます。たとえば、このスケジュールに従って実行されているジョブのインスタンスが 02:01 に完了したとすると、次回のジョブは 5 分間待機して 02:06 に開始されます。

  • 開始時刻の間隔: cron サービスによって各ジョブが開始される一定の時間間隔を定義します。終了時刻の間隔とは異なり、開始時刻の間隔では、前のジョブが完了またはタイムアウトした時刻に関係なく各ジョブが実行されます。ジョブを実行する時間範囲を設定することも、00:00 から 1 日 24 時間、ジョブを実行するように設定することもできます。

    ジョブの開始時刻が厳密に決まっているので、ジョブ インスタンスの実行時間が定義された時間間隔よりも長くなった場合、cron サービスはジョブをスキップすることがあります。つまり、前のジョブが完了もタイムアウトもしなかった場合、その時間の範囲に含まれる開始時刻はスキップされます。

    例: every 5 minutes from 10:00 to 14:00 というスケジュールの場合、最初のジョブは 10:00 に開始され、以後 5 分おきにジョブが実行されます。ただし、最初のジョブの実行に 7 分かかったとすると、10:05 のジョブはスキップされ、cron サービスは 10:10 までこのジョブの次のインスタンスを実行しません。

カスタムの間隔

カスタムの間隔を使用してスケジュールを定義することもできます。この場合、1 つ以上の日付と 1 つ以上の月を選択してジョブを 1 日に 1 回実行できます。カスタムの間隔のスケジュールに従って実行されるジョブは、年間を通じて、選択した日付および月の特定の時刻にのみ実行されます。

例: 1,2,3 of month 07:00 というスケジュールの場合、各月の 1~3 日の 07:00 に 1 回ジョブが実行されます。

schedule に関する重要な考慮事項:

  • 設定する間隔を、1 日以内の間隔とカスタムの間隔のどちらにするかを決める必要があります。タイプの異なる間隔の要素を組み合わせて使用することはできません。たとえば、schedule: every 6 hours mon,wed,fri というスケジュールの定義は無効です。
  • ある時点で実行するジョブのインスタンスは 1 つのみにする必要があります。cron サービスは、「少なくとも 1 回」を基本に処理を行うよう設計されています。つまり、ジョブがスケジュールされると、App Engine はそのジョブのリクエストを少なくとも 1 回は送信します。まれに、同じジョブの複数のインスタンスがリクエストされる可能性があるため、使用するリクエスト ハンドラはべき等性を備えていること、また、そのような状況が発生した場合にも有害な副作用がないようにコードを記述することが大切です。

schedule の書式

ジョブが実行される時期を指定するには、以下の構文を使用して schedule 要素を定義する必要があります。

schedule: [TYPE] [INTERVAL_VALUE] [INTERVAL_SCOPE]

間隔のタイプを選択して、schedule 要素を定義します。

終了時刻の間隔
  • [TYPE]: 毎日実行する間隔には every 接頭辞を含める必要があります。

    例: schedule: every 12 hours

  • [INTERVAL_VALUE]: 整数値とそれに対応する時間の単位。有効な時間の単位は次のとおりです。
    • minutes または mins
    • hours
  • [INTERVAL_SCOPE]: 該当しません。ジョブを実行する特定の開始時刻または時間範囲を設定するには、開始時刻の間隔またはカスタムの間隔の構文をご覧ください。
終了時刻の間隔の例
終了時刻の間隔を使用するジョブのスケジュールの定義方法の理解には、以下の例が参考になります。
  • 毎日 00:00 に実行を開始し、次回のジョブ実行まで 5 分間待機する場合。各ジョブが終了すると、cron サービスは 5 分間待機してから次のジョブを実行します。
    schedule: every 5 minutes
  • 毎日 00:00 に実行を開始し、次回のジョブ実行まで 30 分間待機する場合。各ジョブが終了すると、cron サービスは 30 分間待機してから次のジョブを実行します。
    schedule: every 30 mins
開始時刻の間隔
  • [TYPE]: 毎日実行する間隔には every 接頭辞を含める必要があります。

    例: schedule: every 12 hours

  • [INTERVAL_VALUE]: 整数値とそれに対応する時間の単位。有効な時間の単位は次のとおりです。
    • minutes または mins
    • hours
  • [INTERVAL_SCOPE]: [INTERVAL_VALUE] に対応する句を指定します。カスタム時間範囲を定義するか、24 時間の synchronized オプションを使用できます。
    • from [HH:MM] to [HH:MM] 句を含めて、ジョブを実行する特定の開始時刻と範囲を定義します。

      時刻の値を 24 時間形式の HH:MM で指定します。ここで、

      • HH00 から 23 までの整数です。
      • MM00 から 59 までの整数です。
    • 24 時間の時間範囲(from 00:00 to 23:59)を指定し、それを [INTERVAL_VALUE] の値で均等に分割する場合は、synchronized を使用します。

      重要: [INTERVAL_VALUE] に指定する値は 24 の約数でなければなりません。そうでないと、エラーが発生します。つまり [INTERVAL_VALUE] の有効な値は、1234681224 です。

開始時刻の間隔の例
開始時刻の間隔を使用してジョブのスケジュールを定義する場合は、以下の例を参考にしてください。
  • 毎日 10:00~14:00 に 5 分間隔で実行する:
    schedule: every 5 minutes from 10:00 to 14:00
  • 毎日 08:00~16:00 に 1 時間ごとに実行する:
    schedule: every 1 hours from 08:00 to 16:00
  • 毎日 00:00 を起点として 2 時間ごとに実行する:
    schedule: every 2 hours synchronized
カスタムの間隔
  • [TYPE]: カスタムの間隔では、every 接頭辞を含めて繰り返しの間隔を定義するか、月の日付の明細リストを定義できます。
    • 繰り返しの間隔を定義するには、every 接頭辞を使用します。

      例:

      schedule: every day 00:00
      schedule: every monday 09:00

    • 具体的な日付を定義する場合は、序数を使用する必要があります。有効な値は、月の初日からその月の最終日を表す値までです。たとえば、次のようになります。
      • 1st または first
      • 2nd または second
      • 3rd または third
      • 最大値: 31st または thirtyfirst

      例:

      schedule: 1st,3rd tuesday
      schedule: 2nd,third wednesday of month 09:00

  • [INTERVAL_VALUE]: カスタムの間隔には、ジョブを実行する具体的な日付や曜日を含めることができます。リストはカンマ区切りで定義する必要があり、以下のいずれかの値を含めることができます。
    • その月の日付を表す整数値で、最大 31 日まで。たとえば、次のようになります。
      • 1
      • 2
      • 3
      • 最大 31
    • 曜日名を表す次の長い名前または短縮形の任意の組み合わせ:
      • monday または mon
      • tuesday または tue
      • wednesday または wed
      • thursday または thu
      • friday または fri
      • saturday または sat
      • sunday または sun
      • すべての曜日を指定するには、day を使用します。

    例:

    schedule: 2nd monday,thu
    schedule: 1,8,15,22 of month 09:00
    schedule: 1st mon,wednesday,thu of sep,oct,nov 17:00

  • [INTERVAL_SCOPE]: 指定した [INTERVAL_VALUE] に対応する句を指定します。カスタムの間隔には、年内の特定のひと月または複数の月のカンマ区切りのリストを指定する of [MONTH] 句を指定できます。また、ジョブを実行する具体的な時刻を of [MONTH] [HH:MM] のように定義する必要があります。

    of 句を省略した場合のデフォルトでは、カスタムの間隔は毎月実行されます。

    • [MONTH]: 複数月はカンマ区切りのリストで指定します。月の値には以下の長い名前と短縮形を混在させることができます。
      • january または jan
      • february または feb
      • march または mar
      • april または apr
      • may
      • june または jun
      • july または jul
      • august または aug
      • september または sep
      • october または oct
      • november または nov
      • december または dec
      • すべての月を指定するには、month を使用します。
    • [HH:MM]: 時刻の値を 24 時間形式の HH:MM で指定する必要があります。
      • HH00 から 23 までの整数です。
      • MM00 から 59 までの整数です。
    • 例:

      schedule: 1st monday of sep,oct,nov 09:00
      schedule: 1 of jan,april,july,oct 00:00

カスタムの間隔の例
カスタムの間隔を使用してジョブのスケジュールを定義する場合は、以下の例を参考にしてください。
  • 毎日 00:00 に実行する:
    schedule: every day 00:00
  • 毎週月曜日の 09:00 に実行する:
    schedule: every monday 09:00
  • 3 月の第 2 水曜日の 17:00 に 1 回だけ実行する:
    schedule: 2nd wednesday of march 17:00
  • 5 月の最初の 2 週の月曜日、水曜日、金曜日の 10:00 に 1 回ずつ、つまり合計で 6 回実行する:
    schedule: 1st,second mon,wed,fri of may 10:00
  • 1 週間に 1 回実行する。毎月 1 日を起点として 7 日ごとの 09:00 に 1 回実行する:
    schedule: 1,8,15,22 of month 09:00
  • 隔週で実行する。毎月第 1 および第 3 月曜日の 04:00 に 1 回実行する:
    schedule: 1st,third monday of month 04:00
  • 毎年 3 回実行する。9 月、10 月、11 月の第 1 月曜日の 09:00 に 1 回実行する:
    schedule: 1st monday of sep,oct,nov 09:00
  • 四半期ごとに 1 回実行する。1 月、4 月、7 月、10 月の初日の 00:00 に 1 回実行する:
    schedule: 1 of jan,april,july,oct 00:00

再試行を指定する

cron ジョブのリクエスト ハンドラが 200~299 ではないステータス コードを返した場合、App Engine はジョブが失敗したものとみなします。デフォルトでは、失敗したジョブは再試行されません。構成ファイルに retry_parameters ブロックを追加すると、失敗したジョブを再試行できます。

次に cron.yaml ファイルの例を示します。ここでは、1 つの cron ジョブを最大 5 回まで再試行し、その際にバックオフの間隔を 2.5 秒から始めて、再試行ごとに 2 倍ずつ長くしていきます。

cron:
- description: "retry demo"
  url: /retry
  schedule: every 10 mins
  retry_parameters:
    job_retry_limit: 5
    min_backoff_seconds: 2.5
    max_doublings: 5

cron 再試行構文

次の表で、再試行パラメータを説明します。

要素 説明
job_retry_limit 失敗した cron ジョブの再試行回数の最大値を表す整数。最小値は 0、最大値は 5 です。job_age_limit も指定した場合、App Engine は両方の上限に達するまで cron ジョブを再試行します。job_retry_limit のデフォルト値は 0 です。
job_age_limit 失敗した cron ジョブを再試行する制限時間。cron ジョブを最初に実行した時点から計測されます。値は数値の後に時間の単位を付けたものです。単位は、s が秒、m が分、h が時間、d が日を表します。たとえば、5d という値は、cron ジョブの実行の初回試行時から 5 日後までという制限を指定します。job_retry_limit も指定した場合、App Engine は両方の上限に達するまで cron ジョブを再試行します。
min_backoff_seconds cron ジョブの失敗後、再試行するまで待機する最小時間(秒)。
max_backoff_seconds cron ジョブの失敗後、再試行するまで待機する最大時間(秒)。
max_doublings cron ジョブが失敗して再試行されるまでの間隔が倍増する最大回数。その後、再試行間隔は一定になります。定数は 2**(max_doublings - 1) * min_backoff です。

cron リクエストを検証する

cron URL に対するリクエストが App Engine から発生したものであり、他のソースではないことを確認する場合があります。これを確認するには、リクエストの HTTP ヘッダーと送信元 IP アドレスを検証します。

  • cron サービスからのリクエストには、次の HTTP ヘッダーが含まれます。

    X-Appengine-Cron: true
    

    このヘッダーとその他のヘッダーは、App Engine によって内部的に設定されます。クライアントがこれらのヘッダーを送信すると、リクエストから削除されます。

  • App Engine は、cron リクエストを IP アドレス 0.1.0.2 から発行します。古い gcloud バージョン(326.0.0 より前)で作成された cron ジョブの場合、cron リクエストは 0.1.0.1 から送信されます。

cron ジョブをアップロードする

cron ジョブをアップロードするには、パラメータに cron.yamlを指定して次の gcloud コマンドを実行します。

gcloud app deploy cron.yaml

cron ジョブを削除する

すべての cron ジョブを削除するには、次の内容だけが含まれるように cron.yaml ファイルを変更します。

cron:

Google Cloud コンソールでの cron のサポート

スケジュールされた cron ジョブは、Google Cloud コンソールの [cron ジョブ] ページで確認できます。

また、[ログ] ページでは、cron ジョブがいつ追加または削除されたかを確認できます。