- 更新日: 2016年12月6日
 - Rails
 
Railsでwheneverによるcronバッチ処理
whenever は、cron ジョブを Ruby のシンタックスで簡潔に書くことができる gem です。whenever を利用すれば、定期的に cron で実行したいバッチ処理等を作成しやすく、また管理しやすくなります。使い方も簡単です。
https://github.com/javan/whenever
この記事は、Rails プロジェクトでの whenever 導入から、cron ジョブの作成・実行までの流れの説明となります。
— 環境 —
rails 5.0.0.1
whenever 0.9.7
capistrano 3.6.1
whenever をインストール
まずは whenever の gem をインストールします。Gemfile に追記後、bundle install。
Gemfile
| 
					 1  | 
						gem 'whenever', :require => false  | 
					
| 
					 1 2 3  | 
						$ bundle install  | 
					
初回インストール時は、cron ジョブを管理する config/schedule.rb を生成するために以下コマンドを実行します。
| 
					 1 2 3 4 5  | 
						$ bundle exec wheneverize . [add] writing `./config/schedule.rb' [done] wheneverized!  | 
					
これで config/schedule.rb が生成されました。
実行させる cron ジョブを追加
続いて cron ジョブを Ruby のシンタックスで作成していきます。コードサンプルは、GitHub README のコード例を中心にコメントを追加しました。
config/schedule.rb
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45  | 
						# ログの出力先を設定 set :output, 'log/crontab.log' # production 環境で cron 実行 set :environment, :production # 3時間毎に every 3.hours do # 1.minute 1.day 1.week 1.month 1.year is also supported   # MyModel モデルの some_process クラスメソッドを実行   runner "MyModel.some_process"   # Rake タスクを実行   rake "my:rake:task"   # コマンドを実行   command "/usr/bin/my_great_command" end # 1日1回 AM4:30 に every 1.day, :at => '4:30 am' do   # MyModel モデルの task_to_run_at_four_thirty_in_the_morning クラスメソッドを実行   runner "MyModel.task_to_run_at_four_thirty_in_the_morning" end # 1時間毎に every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot   # SomeModel モデルの ladeeda クラスメソッドを実行   runner "SomeModel.ladeeda" end every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday   # 日曜日のPM12:00 に Task モデルの do_something_great クラスメソッドを実行   runner "Task.do_something_great" end # 毎月27〜31日の 00:00 に every '0 0 27-31 * *' do   # コマンドを実行   command "echo 'you can use raw cron syntax too'" end # run this task only on servers with the :app role in Capistrano # see Capistrano roles section below # role が :app のサーバーで、毎日 AM 12:20 に every :day, :at => '12:20am', :roles => [:app] do   # Rake タスクを実行   rake "app_server:task" end  | 
					
各々実行させたいモデルのクラスメソッドや Rake タスク等は、別途自力で実装する必要があります。
また、Rake タスクを実行させたい場合は、エラーが出るかもしれないので注意。エラーになった場合は下記エントリーをご参考ください。
wheneverで/bin/bash: bundle: command not foundエラー | EasyRamble
whenever で設定した cron ジョブの確認・更新・削除
whenever で追加した cron ジョブを確認します。
| 
					 1 2 3  | 
						$ bundle exec whenever  | 
					
この段階では、まだ crontab には反映されません。crontab に反映するには、–update-crontab オプションを使う。
| 
					 1 2 3  | 
						$ bundle exec whenever --update-crontab  | 
					
ここで crontab を確認すると whenever で設定したジョブが反映されるはずです。crontab 確認。
| 
					 1 2 3  | 
						$ crontab -e  | 
					
crontab に反映した cron ジョブを削除。
| 
					 1 2 3  | 
						$ bundle exec whenever --clear-crontab  | 
					
Capistrano デプロイ時に whenever による crontab を更新する
Capfile 内で whenever/capistrano を require させます。
Capfile
| 
					 1  | 
						require "whenever/capistrano"  | 
					
config/deploy.rb
続いて Capistrano 用デプロイスクリプト(config/deploy.rb)に以下を追加。
config/deploy.rb
| 
					 1 2 3 4  | 
						set :whenever_environment, "#{fetch(:stage)}" set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" } SSHKit.config.command_map[:whenever] = "bundle exec whenever"  | 
					
これで Capistrano によるデプロイで、whenever でスケジューリング設定した cron ジョブが crontab に自動で反映されるようになります。
Capistrano でデプロイ実行。
| 
					 1 2 3  | 
						$ bundle exec cap production deploy  | 
					
production サーバーで crontab を確認して反映されていればOKです。今後は、config/schedule.rb を編集後にデプロイすると、crontab が自動で更新されます。
- Rails の関連記事
 - RailsでMySQLパーティショニングのマイグレーション
 - Rails ActiveRecordでdatetime型カラムのGROUP BY集計にタイムゾーンを考慮する
 - RailsプラグインGemの作成方法、RSpecテストまで含めたrails pluginの作り方
 - RailsでAMPに対応するgemをリリースしました
 - Railsでrequest.urlとrequest.original_urlの違い
 - Google AnalyticsのRails Turbolinks対応
 - Railsアプリにソーシャル・シェアボタンを簡単設置
 - Rails監視ツール用にErrbitをHerokuで運用
 - Facebook APIバージョンのアップグレード手順(Rails OmniAuth)
 - window.NREUMがHTMLヘッダー部に自動挿入されるのはNew Relic用
 

画像付き英語辞書 Imagict | 英単語をイメージで暗記





Leave Your Message!