Rails ortamında zamanlanmış görevleri çalıştırmanın en iyi yolu nedir? Senaryo / koşucu? Tırmık? Görevi birkaç dakikada bir çalıştırmak istiyorum.
Rails ortamında zamanlanmış görevleri çalıştırmanın en iyi yolu nedir? Senaryo / koşucu? Tırmık? Görevi birkaç dakikada bir çalıştırmak istiyorum.
Yanıtlar:
Komisyon yaklaşımını kullanıyorum ( heroku tarafından desteklendiği gibi )
Lib / tasklar / cron.rake adlı bir dosya ile ..
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
Komut satırından yürütmek için bu sadece "komisyon cron". Bu komut daha sonra istendiği gibi işletim sistemi cron / görev zamanlayıcısına konabilir.
Güncelleme bu oldukça eski bir soru ve cevap! Bazı yeni bilgiler:
load "#{Rails.root}/lib/tasks/cron.rake"
ve rake cron
fakat NameError var: tanımsız yerel değişken ya da ana yöntemi `cron'u': Nesne
:environment
bağımlılıktır. Başlaması uzun süren çok ağır bir Rails uygulamamız var, Komisyonumuz her dakika çağrılıyor ve görevi yerine getiren Rails ortamını başlatan daha fazla kaynak tüketiyor . Daha önce başlatılmış bir Rails ortamının cron üzerinden çağrılmasını isterdim , kontrolör yaklaşımı ve tırmık ortamı arasında bir şey olmalı .
Ben son derece popüler kullandım ne zaman zamanlanmış görevler temeline dayanmaktadır üzerinde projeler ve bu harika. Crontab formatıyla uğraşmak yerine zamanlanmış görevlerinizi tanımlamanız için size güzel bir DSL sunar. README'den:
Cron işlerini yazmak ve dağıtmak için açık bir sözdizimi sağlayan bir Ruby taşı olduğunda.
README'den bir örnek:
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
Projemizde ilk kez mücevher kullandığımız halde bazı sorunlarla karşılaştık.
Daha sonra RUFUS SCHEDULER gemine geçtik, bu da Rails'teki görevleri zamanlamak için çok kolay ve güvenilir olduğu ortaya çıktı.
Haftalık ve günlük posta göndermek ve hatta periyodik komisyon görevleri veya herhangi bir yöntem yürütmek için kullandık.
Burada kullanılan kod şöyledir:
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
Daha fazla bilgi edinmek için: https://github.com/jmettraux/rufus-scheduler
Görevlerinizin tamamlanması çok uzun sürmüyorsa, her görev için bir eylem içeren yeni bir denetleyici oluşturun. Görevin mantığını denetleyici kodu olarak uygulayın, Daha sonra bu denetleyicinin URL'sini ve eylemi uygun zaman aralıklarında çağırmak için wget kullanan işletim sistemi düzeyinde bir cronjob oluşturun. Bu yöntemin avantajları:
script / runner ve rake görevleri cron işleri olarak çalışmak için mükemmeldir.
İşte cron işlerini çalıştırırken hatırlamanız gereken çok önemli bir şey. Muhtemelen uygulamanızın kök dizininden çağrılmazlar. Bu, dosyalara (kitaplıkların aksine) ilişkin tüm gereksinimlerinizin açık yolla yapılması gerektiği anlamına gelir: örn. File.dirname (__ FILE__) + "/ other_file". Bu aynı zamanda onları başka bir dizinden nasıl açıkça arayacağınızı bilmeniz gerektiği anlamına gelir :-)
Kodunuzun başka bir dizinden çalıştırılmasını destekleyip desteklemediğini kontrol edin
# 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
Ayrıca, cron işleri muhtemelen sizin gibi çalışmaz, bu nedenle .bashrc'ye koyduğunuz herhangi bir kısayola güvenmeyin. Ama bu sadece standart bir cron ipucu ;-)
Her zaman (ve cron) ile ilgili sorun, her yürütüldüğünde raylar ortamını yeniden yüklemesidir, bu da görevleriniz sık olduğunda veya çok fazla başlatma işi olduğunda gerçek bir sorundur. Bu yüzden üretimde sorunlar yaşadım ve sizi uyarmalıyım.
Rufus zamanlayıcı bunu benim için yapıyor ( https://github.com/jmettraux/rufus-scheduler )
Çalışacak uzun işlerim olduğunda, gecikmeli_job ile kullanıyorum ( https://github.com/collectiveidea/delayed_job )
Umarım bu yardımcı olur!
Resque / resque scheduler hayranıyım . Yalnızca yinelenen cron benzeri görevleri değil, belirli zamanlarda görevleri de çalıştırabilirsiniz. Dezavantajı, bir Redis sunucusu gerektirir.
Hiç kimse Sidetiq'ten bahsetmedi . Zaten Sidekiq kullanıyorsanız güzel bir ektir.
Sidetiq, Sidekiq için yinelenen çalışanları tanımlamak için basit bir API sağlar.
İş şu şekilde görünecektir:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
Her ikisi de iyi çalışır. Genellikle script / runner kullanıyorum.
İşte bir örnek:
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
Veritabanınıza bağlanmak için doğru yapılandırma dosyalarını yüklerseniz, bunu yapmak için salt Ruby komut dosyası da yazabilirsiniz.
Bellek değerliyse akılda tutulması gereken bir şey, komut dosyasının / koşucunun (veya 'ortama bağlı bir Komisyon görevinin) tüm Rails ortamını yükleyeceğidir. Veritabanına yalnızca bazı kayıtlar eklemeniz gerekiyorsa, bu gerçekten gerekli olmayan belleği kullanır. Kendi komut dosyanızı yazarsanız, bundan kaçınabilirsiniz. Bunu henüz yapmam gerekmiyordu, ama bunu düşünüyorum.
Craken kullanın (tırmık merkezli cron işleri)
Backgroundrb kullanıyorum.
http://backgroundrb.rubyforge.org/
Zamanlanmış görevleri ve normal istemci / sunucu ilişkisi için çok uzun süren görevleri çalıştırmak için kullanıyorum.
İşte cron görevlerimi nasıl ayarladım. Ben bir SQL veritabanı günlük komisyon yapmak (komisyon kullanarak) ve başka bir ayda bir kez önbellek süresi var. Çıktılar bir dosya günlüğüne / cron_log dosyasına kaydedilir. Crontab'ım şöyle:
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
İlk cron görevi günlük db yedeklemeleri yapar. Cron_tasks içeriği aşağıdaki gibidir:
/usr/local/bin/rake db:backup RAILS_ENV=production; date; echo "END OF OUTPUT ----";
İkinci görev daha sonra ayarlandı ve önbelleği ayda bir kez sona erdirmek için script / runner kullanıyor (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}"
Ben başka bir şekilde veritabanı yedekleme olabilir sanırım ama şimdiye kadar benim için çalışıyor :)
Yolları komisyon, yakut farklı sunucularda değişebilir. Nerede olduklarını kullanarak şunları görebilirsiniz:
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
Bir şey Sidekiq veya Resque kullanmak çok daha sağlam bir çözümdür. Her ikisi de yeniden deneme işlerini, REDIS kilidi ile ayrıcalığı, izleme ve zamanlamayı destekler.
Resque'un ölü bir proje (aktif olarak korunmayan) olduğunu unutmayın, bu nedenle Sidekiq daha iyi bir alternatiftir. Ayrıca daha performanslıdır: Sidekiq birkaç işçiyi tek ve çok iş parçacıklı bir işlemde çalıştırırken Resque her işçiyi ayrı bir işlemde çalıştırır.
Son zamanlarda üzerinde çalıştığım projeler için bazı cron işleri yarattım.
Gem Clockwork çok yararlı buldum .
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
Hatta bu taş kullanarak arka plan iş planlayabilirsiniz. Dokümantasyon ve daha fazla yardım için https://github.com/Rykian/clockwork adresine bakın.
cron oluşturmak için kullanabilirsiniz resque
ve resque-schedular
gem, bu yapmak çok kolaydır.
Bir keresinde aynı kararı vermek zorunda kaldım ve bugün bu karardan gerçekten memnunum. Resque zamanlayıcı kullanın, çünkü sadece ayrı bir redis yükü db'nizden çıkarmaz, aynı zamanda mükemmel bir kullanıcı arayüzü sağlayan resque-web gibi birçok eklentiye de erişebilirsiniz. Sisteminiz geliştikçe, zamanlamak için daha fazla göreve sahip olacaksınız, böylece onları tek bir yerden kontrol edebileceksiniz.
Muhtemelen bunu yapmanın en iyi yolu, ihtiyacınız olan görevleri yazmak için tırmık kullanmak ve sadece komut satırı üzerinden yürütmektir.
Raylı yayınlarda çok yararlı bir video görebilirsiniz
Ayrıca bu diğer kaynaklara da göz atın:
Gerçekten emin değilim, sanırım göreve göre değişir: ne sıklıkta çalıştırılacağı, ne kadar karmaşık ve raylar projesi ile ne kadar doğrudan iletişim gerekli vb. Sanırım bir şey yapmak için sadece "Tek En İyi Yol" , bunu yapmanın pek çok farklı yolu olmazdı.
Bir Rails projesindeki son işimde, sunucunun zamanı olduğunda planlanan postaları göndermesi gereken bir toplu davet postası (anket davetiyeleri, spam değil) yapmamız gerekiyordu. Sanırım yarattığım tırmıklama görevlerini yürütmek için daemon araçlarını kullanacağız .
Ne yazık ki, şirketimizin bazı para sorunları vardı ve ana rakip tarafından "satın alındı" böylece proje asla tamamlanmadı, bu yüzden sonunda ne kullanacağımızı bilmiyorum.
Ben cron çalıştırmak için komut dosyası kullanın, bu bir cron çalıştırmak için en iyi yoldur. İşte cron için bir örnek,
CronTab'ı açın -> sudo crontab -e
Ve Körük çizgilerini yapıştırın:
00 00 * * * wget https: // your_host / some_API_end_point
İşte bazı cron formatı, size yardımcı olacak
::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.
Bu size yardımcı olacağını umuyoruz :)