Rails環境でスケジュールされたタスクを実行する最良の方法は何ですか?スクリプト/ランナー?レーキ?数分ごとにタスクを実行したいと思います。
Rails環境でスケジュールされたタスクを実行する最良の方法は何ですか?スクリプト/ランナー?レーキ?数分ごとにタスクを実行したいと思います。
回答:
私はレイクアプローチを使用しています(herokuでサポートされています)
lib / tasks / cron.rakeというファイルを使用します。
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
コマンドラインから実行する場合、これは単に "rake cron"です。このコマンドは、必要に応じてオペレーティングシステムのcron /タスクスケジューラに配置できます。
更新これはかなり古い質問と答えです!いくつかの新しい情報:
load "#{Rails.root}/lib/tasks/cron.rake"
しましrake cron
たが、NameError:undefined local variable or method `cron 'for main:Object
:environment
依存関係です。起動に時間がかかる非常に重いRailsアプリケーションがあり、Rakeは毎分呼び出され、タスクを実行するRails環境を起動するためにより多くのリソースを消費します。すでに起動されている Rails環境をcronから呼び出すようにしたいのですが、コントローラーアプローチとrake環境の間の何かである必要があります。
私は非常に人気のあるWheneverを、スケジュールされたタスクに大きく依存するプロジェクトで使用してきました。crontab形式を処理する必要がなく、スケジュールされたタスクを定義するための優れたDSLを提供します。READMEから:
いつでも、cronジョブを記述およびデプロイするための明確な構文を提供するRuby gemです。
READMEの例:
every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"
end
every 1.day, :at => '4:30 am' do
runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end
私たちのプロジェクトでは、最初にいつでも宝石を使用しましたが、いくつかの問題に直面しました。
次に、RUFUS SCHEDULER gemに切り替えました。このgemは、Railsでのタスクのスケジューリングにとって非常に簡単で信頼できることがわかりました。
毎週および毎日メールを送信するために、そしていくつかの定期的なレーキタスクまたは任意の方法を実行するためにさえ、それを使用しました。
この中で使用されるコードは次のようなものです:
require 'rufus-scheduler'
scheduler = Rufus::Scheduler.new
scheduler.in '10d' do
# do something in 10 days
end
scheduler.at '2030/12/12 23:30:00' do
# do something at a given point in time
end
scheduler.every '3h' do
# do something every 3 hours
end
scheduler.cron '5 0 * * *' do
# do something every day, five minutes after midnight
# (see "man 5 crontab" in your terminal)
end
タスクの完了にそれほど時間がかからないと想定して、各タスクのアクションを持つ新しいコントローラーを作成してください。タスクのロジックをコントローラーコードとして実装してから、wgetを使用して適切な時間間隔でこのコントローラーのURLとアクションを呼び出すOSレベルでcronjobを設定します。この方法の利点は次のとおりです。
スクリプト/ランナーおよびrakeタスクは、cronジョブとして実行するのに完全に適しています。
ここでは、cronジョブを実行するときに覚えておく必要がある非常に重要な事項を1つ示します。おそらくアプリのルートディレクトリから呼び出されることはありません。これは、(ライブラリではなく)ファイルに必要なすべてのことを明示的なパスで行う必要があることを意味します:たとえば、File.dirname(__ FILE__)+ "/ other_file"。これはまた、別のディレクトリから明示的に呼び出す方法を知っている必要があることも意味します:-)
コードが別のディレクトリからの実行をサポートしているかどうかを確認してください
# from ~
/path/to/ruby /path/to/app/script/runner -e development "MyClass.class_method"
/path/to/ruby /path/to/rake -f /path/to/app/Rakefile rake:task RAILS_ENV=development
また、cronジョブはおそらくあなたのように実行されないので、.bashrcに入れたショートカットに依存しないでください。しかし、それは単なる標準のcronヒントです;-)
いつでも(およびcron)の問題は、実行されるたびにRails環境がリロードされることです。これは、タスクが頻繁に行われる場合や、初期化作業が大量に行われる場合に実際の問題です。このため、生産に問題があり、警告する必要があります。
Rufusスケジューラーがそれを行います(https://github.com/jmettraux/rufus-scheduler)
実行するジョブが長い場合は、delayed_job(https://github.com/collectiveidea/delayed_job)で使用します。
これが役に立てば幸いです!
私はresque / resqueスケジューラーの大ファンです。cronのようなタスクを繰り返すだけでなく、特定の時間にタスクを実行することもできます。欠点は、Redisサーバーが必要になることです。
どちらも正常に動作します。私は通常スクリプト/ランナーを使用します。
次に例を示します。
0 6 * * * cd /var/www/apps/your_app/current; ./script/runner --environment production 'EmailSubscription.send_email_subscriptions' >> /var/www/apps/your_app/shared/log/send_email_subscriptions.log 2>&1
データベースに接続するための適切な構成ファイルをロードする場合、pure-Rubyスクリプトを記述してこれを行うこともできます。
メモリが貴重な場合に留意すべきことの1つは、スクリプト/ランナー(または「環境」に依存するRakeタスク)がRails環境全体をロードすることです。一部のレコードをデータベースに挿入するだけでよい場合は、実際には必要のないメモリを使用します。独自のスクリプトを作成すると、これを回避できます。実際にこれを行う必要はまだありませんが、検討中です。
Craken(Rake中心のcronジョブ)を使用する
私はbackgroundrbを使用しています。
http://backgroundrb.rubyforge.org/
これを使用して、スケジュールされたタスクや、通常のクライアント/サーバー関係では時間がかかりすぎるタスクを実行します。
cronタスクを設定する方法は次のとおりです。SQLデータベースのバックアップを毎日(rakeを使用して)作成するものと、月に1回キャッシュを期限切れにするものがあります。出力はファイルlog / cron_logに記録されます。私のcrontabは次のようになります。
crontab -l # command to print all cron tasks
crontab -e # command to edit/add cron tasks
# Contents of crontab
0 1 * * * cd /home/lenart/izziv. whiskas.si/current; /bin/sh cron_tasks >> log/cron_log 2>&1
0 0 1 * * cd /home/lenart/izziv.whiskas.si/current; /usr/bin/env /usr/local/bin/ruby script/runner -e production lib/monthly_cron.rb >> log/cron_log 2>&1
最初のcronタスクは、毎日のdbバックアップを作成します。cron_tasksの内容は次のとおりです。
/usr/local/bin/rake db:backup RAILS_ENV=production; date; echo "END OF OUTPUT ----";
2番目のタスクは後でセットアップされ、スクリプト/ランナーを使用して月に1回キャッシュを期限切れにします(lib / monthly_cron.rb):
#!/usr/local/bin/ruby
# Expire challenge cache
Challenge.force_expire_cache
puts "Expired cache for Challenges (Challenge.force_expire_cache) #{Time.now}"
私は他の方法でデータベースをバックアップできると思いますが、今のところそれは私にとってはうまくいきます:)
rakeおよびrubyへのパスは、サーバーによって異なる場合があります。以下を使用して、それらがどこにあるかを確認できます。
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
SidekiqまたはResqueを使用すると、はるかに堅牢なソリューションになります。どちらもジョブの再試行、REDISロックによる排他性、監視、およびスケジューリングをサポートしています。
Resqueは死んだプロジェクト(積極的にメンテナンスされていない)なので、Sidekiqがより良い代替手段であることを覚えておいてください。また、パフォーマンスも向上しています。Sidekiqは単一のマルチスレッドプロセスで複数のワーカーを実行し、Resqueは各ワーカーを個別のプロセスで実行します。
私は最近取り組んでいるプロジェクトのためにいくつかのcronジョブを作成しました。
時計仕掛けの宝石がとても便利だと思いました。
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
この宝石を使用してバックグラウンドジョブをスケジュールすることもできます。ドキュメントと詳細なヘルプについては、https://github.com/Rykian/clockworkを参照してください
あなたが使用することができますresque
し、resque-schedular
逸品のcronを作成するために、これを行うのは非常に簡単です。
おそらくそれを行うための最良の方法は、rakeを使用して必要なタスクを記述し、コマンドラインから実行することです。
railscastsで非常に役立つビデオを見ることができます
この他のリソースもご覧ください。
よくわかりません。タスクに依存していると思います。実行する頻度、複雑さ、そしてRailsプロジェクトとの直接通信がどれだけ必要かなどです。何かを行うには、「最善の方法」が1つだけあるのではないかと思います。、それを行うにはそれほど多くの異なる方法はありません。
Railsプロジェクトでの最後の仕事では、サーバーに時間があるときはいつでも計画されたメールを送信するバッチ招待メーラー(スパムではなく調査招待)を作成する必要がありました。デーモンツールを使用して、作成したRakeタスクを実行するつもりだったと思います。
残念ながら、私たちの会社にはいくつかのお金の問題があり、主要なライバルによって「購入」されたため、プロジェクトは完了しなかったため、最終的に何を使用したのかわかりません。
スクリプトを使用してcronを実行します。これは、cronを実行する最良の方法です。ここにcronのいくつかの例があります、
CronTabを開きます—> sudo crontab -e
そしてベローズラインを貼り付けます:
00 00 * * * wget https:// your_host / some_API_end_point
ここにいくつかのcron形式があります。
::CRON FORMAT::
Examples Of crontab Entries
15 6 2 1 * /home/melissa/backup.sh
Run the shell script /home/melissa/backup.sh on January 2 at 6:15 A.M.
15 06 02 Jan * /home/melissa/backup.sh
Same as the above entry. Zeroes can be added at the beginning of a number for legibility, without changing their value.
0 9-18 * * * /home/carl/hourly-archive.sh
Run /home/carl/hourly-archive.sh every hour, on the hour, from 9 A.M. through 6 P.M., every day.
0 9,18 * * Mon /home/wendy/script.sh
Run /home/wendy/script.sh every Monday, at 9 A.M. and 6 P.M.
30 22 * * Mon,Tue,Wed,Thu,Fri /usr/local/bin/backup
Run /usr/local/bin/backup at 10:30 P.M., every weekday.
これがあなたに役立つことを願っています:)