Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

【保存版】Rubyでcronジョブをスケジュールする方法!whenever gemの使い方を徹底解説

Cronとは?

Cronは、LinuxやmacOSに標準で搭載されているジョブスケジューリングシステムです。

指定した日時に任意のプログラムを自動実行できるのが最大の特徴で、もちろんRubyのコードも実行対象に含まれます。

「毎日」「毎週」「毎時間」など、定期的に繰り返し実行したいタスクがあるなら、Cronがまさに求めているソリューションとなるでしょう。

Cronの活用例

  • 毎週実行するデータベースのバックアップ
  • Webサイトのアクティビティに関する日次レポートの生成
  • リマインダーメールの自動送信

それでは、Cronを実際に活用する方法を見ていきましょう!

Cronの基本

すべてのユーザーは、実行したいタスクを定義するためのcronファイル(クーロンタブ)を持つことができます。

このファイルはcrontab -eコマンドで編集でき、crontab -lコマンドで登録済みのタスク一覧を確認できます。

cronジョブの記述例:

0 0 * * * /opt/rubies/ruby-2.5.1/bin/rake db:backup

この構文は少し複雑で、毎回手作業でファイルを編集するのは面倒に感じるかもしれません。

「もっと簡単に扱えるgemはないの?」——あります!

whenever gemの使い方

cronの構文は覚えにくいため、wheneverのようなgemを活用すると便利です。

このgemを使えば、RubyのDSLでcronジョブを直感的に定義できます。

まずはgemをインストールしましょう。

続いて、設定ファイルを作成します:

wheneverize .
# [add] config/schedule.rb

生成されたconfig/schedule.rbを開くと、コメントアウトされたサンプルコードが表示されます。不要であれば削除して構いません。

ここでは、「1時間ごとにバックアップを実行するジョブ」を作成してみましょう。

「config/schedule.rb」に以下を記述します:

every 1.hour do
  rake "db:backup"
end

利用できる主なオプション

  • rake:現在のプロジェクトで定義されているrakeタスクを実行(※db:backupはデフォルトでは定義されていないため、動作確認にはdb:versionなどを使うとよいでしょう)
  • runner:Rubyのクラス+メソッドを指定(Archive.backup_nowなど)
  • command:システムコマンドを直接実行

次に、以下のコマンドを実行してcronエントリを生成します。

whenever --update-crontab

crontab -lを実行すれば、新しいエントリが登録されていることを確認できます。

実際の出力例:

0 * * * * /bin/bash -l -c 'cd /home/jesus/testing && RAILS_ENV=production bundle exec rake db:backup --silent'

注目すべき点として、このタスクはproductionモードで実行されるようになっています。

これを変更したい場合は、以下の設定を使用します:

set :environment, "development"

この行はschedule.rbファイルの先頭に記述してください。

また、コマンドラインから環境を指定することも可能です:

whenever --update-crontab --set environment=development

このコマンドを実行すると、すべてのタスクが「development」環境向けに生成されます。

wheneverの応用例

より細かいスケジュール指定も簡単に行えます。

毎週月曜日の18時に実行するタスク:

every :monday, at: "6:00 PM" do
  runner "Mail.send_weekly_newsletter"
end

同じタスクを1日に複数回実行することもできます。

1日に2回実行するタスク:

every :day, at: ["12:00 AM", "12:00 PM"] do
  command "rm tmp/testing.txt"
end

ログ出力とトラブルシューティング

crontabファイルにタスクが登録されていれば(crontab -lで確認)、準備完了です。

では、スケジュールされたタスクが正しく動作しているかどうかは、どうやって確認すればいいのでしょうか?

答えは「ログを出力して確認する」です。

schedule.rbファイルの先頭に以下を追加すると、ロギングが有効になります。

設定例:

set :output, "log/cron.log"

重要なポイントschedule.rbを変更したら、必ずwhenever --update-crontabコマンドを再実行してください。忘れがちですが、これを怠ると変更が反映されません。

ログファイルが空のままの場合は、スケジュールされた時刻になるまで待つ必要があります。

よくあるエラーと対処法

ログに以下のようなエラーが表示される場合:

/bin/bash: bundle: command not found

これは、Cronがあなたが普段使っているものと異なるバージョンのRubyで実行していることを意味します。

rbenvやRVMなどのRubyバージョン管理ツールを使用している場合は、設定を.bashrcではなく.bash_profileから読み込むようにしてください。そうすることで、cronタスクでもバージョン管理ツールが正しく利用できるようになります。

wheneverの代替ツール

wheneverはメンテナンスもしっかり行われている優れたgemですが、他にも選択肢があります。

主な代替ツールの一覧:

  • Heroku Scheduler:Herokuユーザー向けの無料ジョブスケジューリングアドオン。cronほど柔軟ではありませんが、手軽に定期実行を実現できます
  • Rufus Scheduler:cronの代わりにインメモリのスケジューラを提供するRuby gem
  • Sidecloq & Sidekiq-cron:どちらもSidekiq用のアドオンで、Sidekiqに繰り返しタスク機能を追加します

なお、Sidekiq系のアドオンはスケジュール指定に実際のcron構文が必要なため、wheneverほど書きやすくはありません。

その一方で、SidekiqのWeb UIと統合できる点は大きなメリットです。

まとめ

この記事では、whenever gemを使ってRubyでcronジョブをスケジュールする方法を学びました。

ポイントをおさらいすると:

  • CronはLinux/macOS標準のジョブスケジューラで、定期的なタスク自動化に最適
  • whenever gemを使えば、読みやすいRuby DSLでcronジョブを定義できる
  • 変更後は必ずwhenever --update-crontabを実行し、ログ設定で動作を確認する

この記事が役に立ったら、ぜひ周りの方にもシェアしてください。

最後までお読みいただき、ありがとうございました。

  1. Rubyのmapメソッド完全ガイド!配列・ハッシュのデータ変換を実例で解説

    Rubyのmapメソッドは、配列(Array)・ハッシュ(Hash)・範囲(Range)といったコレクションに対して使用できる強力なメソッドです。 mapの主な用途は、データの変換です。 例えば、文字列の配列があった場合、すべての文字列を順番に処理して、各文字を大文字に変換することができます。 また、Userオブジェクトのリストがある場合も同様です。 それらを変換して、対応するメールアドレスや電話番号など、Userクラスに定義された任意の属性のリストを作成できます。 それでは、具体的な使い方を見ていきましょう! Ruby mapメソッドの基本構文 mapの構文は次のようになっています。 a

  2. Rubyでパーサーを自作する方法!StringScannerを使った実装手順を徹底解説

    パース(構文解析)とは、文字列の集まりから意味を読み取り、プログラムが扱える形のデータへと変換する技術です。正規表現でも文字列の解析は可能ですが、すべての場面に適しているわけではありません。 たとえば、正規表現でHTMLを解析するのはあまり良い方法ではないというのは、プログラミング界隈ではよく知られた話です。 Rubyにはnokogiriという強力なライブラリがあり、HTMLの解析はこれに任せられます。しかし、自分でパーサーを一から作ってみると、文字列処理や構文解析の仕組みについて多くのことを学べます。それでは早速始めていきましょう! Rubyでのパースの基本:StringScannerクラス