プライベートのちょっとしたことを、サーバーで毎日自動で実行して楽にしたいと思うのは、エンジニアであれば当然だと思います。でも、その為に自宅でサーバを動かしたり、AWSのマイクロインスタンスを常時立ちあげたりするというのは、お金と手間が掛かるので避けたいところです。そんな悩みを解決する為に、HerokuでJobサーバーを構築するというのは如何でしょうか?
Herokuの課金体系は、dynoという独自の単位です。1つのプロセスで1時間動かしたら1dynoです。そして、現在のところ1アカウントにつき、1ヶ月750dynosが無料で使えます。24(時間)*31(日)だと744dynosになります。つまり1プロセス分は常に無料で使えるということです。これを使ってJobサーバー(バッチサーバ)を構築しようというのが今回の趣旨になります。
ジョブ実行ツールの選定
Herokuでジョブですが、2つあります。一つは公式のアドオンである、Temporize Schedulerを使う方法。もう1つは、clockworkというGemを使う方法です。Temporize Schedulerは、10分単位で起動の指定が出来ます。起動の都度、プロセスが立ち上がるというイメージです。これに対してclockworkは、常時立ち上がっていて秒・分・時間単位でジョブを実行してくれます。常に動いているので、データ収集系にはちょうど良いです。
clockworkの使い方
"Hello clockwork on Heroku - Heroku で定期実行アプリケーションを動かそう! - 君の瞳はまるでルビー - Ruby 関連まとめサイト"に、1から10まで丁寧に説明されています。詳しくはそちらを見て頂ければ大丈夫だと思うので、簡単に説明します。clockworkのサンプルをダウンロードすると、Gemfile,Procfile,clock.rbの3つだけで構成されているのが解ります。Gemfileには当然、必要とするGemのリストが記載されています。Procfileには、Herokuで起動するプロセスを記述が1文が書かれているだけです。
cron: bundle exec clockwork clock.rb
実態になるのが、clock.rbです。
require 'clockwork' include Clockwork handler do |job| puts "Running #{job}" end every(10.seconds, 'frequent.job') every(3.minutes, 'less.frequent.job') every(1.hour, 'hourly.job') every(1.day, 'midnight.job', :at => '00:00')
上記の例では、10秒・3分・1時間・1日ごとにJobが起動されるので、handlerのところでケースを分けて実行するjobを記述すれば大丈夫です。実際に運用してみてですが、ジョブ単位にクラスを分けておくと後々の開発運用が楽です。
clockworkの常駐プロセス
require.rb
require 'hourly_job' job =HourlyJob.new job.call #every(10.seconds, 'frequent.job') #every(3.minutes, 'less.frequent.job') #every(1.hour, 'hourly.job')
処理の実装クラス
hourly_job.rb
class HourlyJob def call #処理 end end
まとめ
ということで比較的簡単に使えるので、定期的に実行するジョブがあればHerokuを使うのも良いのではと思います。私は主に情報収集系のジョブを実行しています。他には、AWS EC2のサーバの定時での起動・停止といったことも出来るのではないでしょうか。是非お試しあれ。
See Also:
Hello clockwork on Heroku - Heroku で定期実行アプリケーションを動かそう! - 君の瞳はまるでルビー - Ruby 関連まとめサイト
Herokuでcron?もう古いかも、それ - Meltdown Countdown rev.
Heroku Scheduler をつかってみた - ToMmY Makes Love with Codes