-
Notifications
You must be signed in to change notification settings - Fork 9
scheduler
Schedulerは、アプリケーション上のジョブをスケジュールされた時間帯に実行するアドオンです。トラディショナルなサーバー環境のcron
に似ています。
Schedulerはベストエフォート型のサービスです。ジョブが実行されることは予定となり、必ず実行が保証されるものではありません。Schedulerは、時々(レアなケースですが)スケジュール化されたジョブの実行をし忘れることがあります。スケジュール化されたジョブの実行がアプリケーションのクリティカルなコンポーネントとなる場合、 実行時間をカスタムしたプロセスを走らせることを推奨します。 こちらの方が、信頼性があり、制御や視覚的な操作が可能となります。
Schedulerアドオンは、one-off dynosを実行します。[one-off dynos]は、毎月チャージされるdynoの使用時間に換算されます。
ダッシュボードは、ジョブの実行をある特定の時間に、10分毎、1時間毎、1日毎に設定することが可能となります。ジョブの呼び出しが行われるとone-off dynosとして実行され、ログ上にscheduler.X
のような形式で出力されます。
Schedulerを使用するには、アドオンのインストールが必要です。:
:::term
$ heroku addons:add scheduler:standard
Schedulerは、毎月のdynoの使用時間に換算されるone-off dynosを実行します。Schedulerのタスクによるdynoの使用時間は、heroku run
やdynoのスケールと同じ仕組みでカウントされます。Herokuからのインボイスには、"scheduler"タイプのdynoとして記載されます。
タスクは、アプリケーション上で実行可能なコマンドであれば、いかなる物も定義可能です。
Railsでは、rake
タスクをセットアップすることが規約です。Railsにスケジュールされたタスクをクリエイトするには、下記のコードをlib/tasks/scheduler.rake
へコピーし、あなたのアプリケーション用にカスタマイズして下さい。
:::ruby
desc "This task is called by the Heroku scheduler add-on"
task :update_feed => :environment do
puts "Updating feed..."
NewsFeed.update
puts "done."
end
task :send_reminders => :environment do
User.send_reminders
end
その他のフレームワークや言語で作成されたアプリケーションでは、タスクとして動作するbin/配下へスクリプトを格納するのが規約となります。以下は、bin/clean-sessions
スクリプトの例です。:
:::ruby
#!/usr/bin/env ruby
require "sequel"
DB = Sequel.connect ENV["DATABASE_URL"]
puts "Cleaning old sessions..."
DB["DELETE FROM sessions WHERE last_seen_at < ?", Time.now - 24*60*60]
puts "done."
タスクを作成し、ローカルで機能していることを確認したら、次のステップは、Heroku上にアプリケーションをデプロイし、タスクのテストを行うことです。これを行うには、heroku run
コマンドを使います。heroku run
は、タスクをHeroku上で走らせるためのコマンドです。:
:::term
$ heroku run rake update_feed
Schedulerは、heroku run
コマンドがジョブを実行するのに使用するone-off dynosと同一のdynoを使用します。そのため、heroku run
コマンドが正常に動作している場合、Schedulerでも同様に正常動作することとなります。
ジョブを実行する頻度と時間をスケジュールするには、My Apps上で、対象のアプリを選択し、Schedulerのダッシュボードを開けて下さい。その後、"General Info"をクリックし、アドオンのドロップダウンから"Scheduler"を選択して下さい。ダッシュボードはコマンドからも起動させることが可能です。:
:::term
$ heroku addons:open scheduler
Schedulerのダッシュボード上で、"Add Job..."をクリックして下さい。タスクを入力し、頻度、dynoサイズ (1X か 2X)、次回の実行時間を選択します。
例えば、rake update_feed
というジョブを追加するとした場合、ジョブの実行を毎時30分に実行するためには、"Hourly"と":30"を選択します。また、毎日夜中にリマインダーを送るrake send_reminders
というジョブを追加するとした場合、"Daily"と"00:00"を選択して下さい。
コマンドを明示する代わりにプロセスタイプを明示して下さい。コマンドはプロセスタイプと関連し、与えられたパラメータで実行されます。詳細はone-off dynosのsyntaxの項を参照して下さい。
スケジュール化されたジョブのログは、logsにscheduler.X
のプロセスとして登録されます。:
:::term
$ heroku logs --ps scheduler.1
2011-02-04T14:10:16-08:00 heroku[scheduler.1]: State changed from created to starting
2011-02-04T14:10:16-08:00 app[scheduler.1]: Starting process with command `bin/clean_sessions`
2011-02-04T14:10:19-08:00 app[scheduler.1]: Deleting stale sessions...
2011-02-04T14:10:27-08:00 app[scheduler.1]: done.
2011-02-04T14:10:28-08:00 heroku[scheduler.1]: State changed from up to complete
スケジュール化されたdynoは、heroku ps
コマンドで確認することが可能です。:
:::term
$ heroku ps
=== scheduler: `bin/clean_sessions`
scheduler.1: complete for 5m
=== web: `bundle exec thin start -p $PORT -e production`
web.1: idle for 3h
スケジュール化されたジョブは、短時間で実行されるタスクを想定しています。時間を要するタスクは、バックグラウンドのjob queueに入れられます。数分以上の時間を要するタスクを実行するには、worker dynoを使用するべきです。
ジョブの暴走を防ぐために、ジョブが頻度以上に時間を要する場合、強制的に終了されます。例えば、10分毎に実行されるジョブは、実行後、10分が経過した時点で強制終了されます。
Schedulerは、ベストエフォートのサービスです。ジョブがスケジュールされた時間に実行される保証はありません。全く実行されない場合もあります。Schedulerは、スケジュールされたプロセスが時折スキップされてしまう事象を既知の問題として認識しています。
HerokuのSchedulerへの代替として、実行時間をカスタムしたプロセスを実行することが考えられます。この機能は、プロセスをスケジュールする作業に、より多くの制御とビジビリティを提供します。また、スケジュール化されたジョブがクリティカルなコンポーネントである本番環境のデプロイに適しています。詳細な情報はこの記事を参照して下さい。