Better Heroku Schedulerを探したらCustom clock processesにたどり着いた
これはHeroku Advent Calendar 2016の11日目の記事です。
HerokuではHeroku Schedulerというcronのようなサービスがあるのですが、使い込むうちに「Daily, Hourly, Every 10 minutesの単位でしかジョブを動かせない」という制限がつらくなってきたので、より良い代替であるCustom clock processesを試してみたという話。
Custom clock processesとは?
clockというプロセスを立ち上げっぱなしにして、そのプロセス内でスケジューリングされたジョブを実行する仕組み。Heroku Schedulerは実行される時だけプロセスが立ち上がるけど、clockの場合は常にプロセスが常駐する。
各言語のScheduler
HerokuのCustom clock processesのドキュメントで触れられているのはJavaとPythonの2種類だけど、各言語ごとにだいたいcron likeなSchedulerが用意されている。今回は自分が慣れているPythonのAPSchedulerを試してみた。
- Java: quartz
- Python: APScheduler
- Ruby: clockwork
- Node.js: node-cron
- Perl: Schedule::Cron
APSchedulerの設定
まずPythonのモジュールのインストールのために、requirements.txtというファイルを用意する。
echo APScheduler > requirements.txt次にProcfileに以下を追記する。
clock: python clock.pyここで指定されているclock.pyがジョブの設定が書かれたファイルになる。どのように記述するべきか、詳しくは公式のドキュメントに書かれている。以下は1分毎にhello worldを出力する設定。
from apscheduler.schedulers.blocking import BlockingScheduler
import subprocess
scheduler = BlockingScheduler()
@scheduler.scheduled_job('interval', minutes=1)
def timed_job():
print("Run notifier")
subprocess.run("hello world", shell=True, check=True)
scheduler.start()最後に、APSchedulerを動かすのにはPythonが必要なので、buildpackを追加。
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-pythonあとはclock.pyをコミットしてディプロイすればOK。
ローカルで試したい場合
ローカルで試してみたい場合は以下のようにAPSchedulerをインストールして、clock.pyを直接呼び出せばOK。
pip install -r requirements.txt
python ./clock.pyCustom clock processesとFree Dyno Hours
Heroku Schedulerは実行する際にプロセスが起動されて、プロセスが動いていた時間だけ無料分のFree Dyno Hoursを消費するのだけど、custom clock processesはworkerのようにclockプロセスが常駐する形になるので、起動していた時間分だけFree Dyno Hoursを消費するようなので注意が必要。webと併用していると倍速でFree Dyno Hoursを消費するので気をつけましょう。
まとめ
Heroku Schedulerよりきめ細かい時限式のジョブを定義したいときはCustom clock processesを使おう!
関連記事
2015-12-07
2016-09-15