Cách tốt nhất để chạy các tác vụ theo lịch trình trong môi trường Rails là gì? Kịch bản / người chạy? Cào? Tôi muốn chạy nhiệm vụ cứ sau vài phút.
Cách tốt nhất để chạy các tác vụ theo lịch trình trong môi trường Rails là gì? Kịch bản / người chạy? Cào? Tôi muốn chạy nhiệm vụ cứ sau vài phút.
Câu trả lời:
Tôi đang sử dụng phương pháp cào (được hỗ trợ bởi heroku )
Với một tệp có tên lib / task / cron.rake ..
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
Để thực hiện từ dòng lệnh, đây chỉ là "rake cron". Lệnh này sau đó có thể được đưa vào bộ lập lịch cron / tác vụ của hệ điều hành như mong muốn.
Cập nhật đây là một câu hỏi và câu trả lời khá cũ! Một số thông tin mới:
load "#{Rails.root}/lib/tasks/cron.rake"
và rake cron
, nhưng có NameError: không xác định biến cục bộ hoặc phương thức `cron 'cho main: Object
:environment
phụ thuộc. Chúng tôi có một ứng dụng Rails rất nặng, mất nhiều thời gian để khởi động, Rake của chúng tôi được gọi mỗi phút và tiêu tốn nhiều tài nguyên hơn bắt đầu từ môi trường Rails thực thi tác vụ . Tôi muốn có một môi trường Rails đã được khởi động để được gọi thông qua cron, phải là một cái gì đó giữa phương pháp điều khiển và môi trường cào .
Tôi đã sử dụng cực kỳ phổ biến Bất cứ khi nào vào các dự án phụ thuộc nhiều vào các nhiệm vụ theo lịch trình, và nó thật tuyệt. Nó cung cấp cho bạn một DSL đẹp để xác định các tác vụ theo lịch trình của bạn thay vì phải xử lý định dạng crontab. Từ README:
Bất cứ khi nào là một viên ngọc Ruby cung cấp một cú pháp rõ ràng để viết và triển khai các công việc định kỳ.
Ví dụ từ 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
Trong dự án của chúng tôi lần đầu tiên chúng tôi sử dụng bất cứ khi nào đá quý, nhưng phải đối mặt với một số vấn đề.
Sau đó, chúng tôi đã chuyển sang đá quý RUFUS SCHEDULER , hóa ra rất dễ dàng và đáng tin cậy để lên lịch các tác vụ trong Rails.
Chúng tôi đã sử dụng nó để gửi thư hàng tuần và hàng ngày, và thậm chí để chạy một số nhiệm vụ cào định kỳ hoặc bất kỳ phương pháp nào.
Mã được sử dụng trong này là như sau:
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
Để tìm hiểu thêm: https://github.com/jmettraux/rufus-scheduler
Giả sử các nhiệm vụ của bạn không mất quá nhiều thời gian để hoàn thành, chỉ cần tạo một bộ điều khiển mới với một hành động cho mỗi nhiệm vụ. Thực hiện logic của tác vụ dưới dạng mã của bộ điều khiển, sau đó thiết lập một cronjob ở cấp hệ điều hành sử dụng wget để gọi URL của bộ điều khiển này và hành động theo các khoảng thời gian thích hợp. Ưu điểm của phương pháp này là bạn:
các tác vụ kịch bản / chạy và cào là hoàn toàn tốt để chạy như các công việc định kỳ.
Đây là một điều rất quan trọng bạn phải nhớ khi chạy các công việc định kỳ. Họ có thể sẽ không được gọi từ thư mục gốc của ứng dụng của bạn. Điều này có nghĩa là tất cả các yêu cầu của bạn đối với các tệp (trái ngược với thư viện) phải được thực hiện với đường dẫn rõ ràng: ví dụ: File.dirname (__ FILE__) + "/ other_file". Điều này cũng có nghĩa là bạn phải biết cách gọi chúng một cách rõ ràng từ một thư mục khác :-)
Kiểm tra xem mã của bạn có hỗ trợ được chạy từ thư mục khác không
# 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
Ngoài ra, các công việc định kỳ có thể không chạy như bạn, vì vậy đừng phụ thuộc vào bất kỳ phím tắt nào bạn đặt .bashrc. Nhưng đó chỉ là một mẹo cron tiêu chuẩn ;-)
Vấn đề với bất cứ khi nào (và cron) là nó tải lại môi trường đường ray mỗi khi nó được thực thi, đây là một vấn đề thực sự khi các tác vụ của bạn thường xuyên hoặc có rất nhiều công việc khởi tạo phải làm. Tôi đã có vấn đề trong sản xuất vì điều này và phải cảnh báo bạn.
Bộ lập lịch Rufus làm điều đó cho tôi ( https://github.com/jmettraux/rufus-scheduler )
Khi tôi có các công việc dài để chạy, tôi sử dụng nó với delay_job ( https://github.com/collectiveidea/delayed_job )
Tôi hi vọng cái này giúp được!
Tôi là một fan hâm mộ lớn của resque / scheduler resque . Bạn không chỉ có thể chạy lặp lại các tác vụ giống như cron mà cả các tác vụ vào những thời điểm cụ thể. Nhược điểm là, nó yêu cầu máy chủ Redis.
Đó là điều thú vị không ai nhắc đến Sidetiq . Đây là một bổ sung tuyệt vời nếu bạn đã sử dụng Sidekiq.
Sidetiq cung cấp một API đơn giản để xác định các nhân viên định kỳ cho Sidekiq.
Công việc sẽ như thế này:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
Cả hai sẽ hoạt động tốt. Tôi thường sử dụng kịch bản / người chạy.
Đây là một ví dụ:
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
Bạn cũng có thể viết tập lệnh Ruby thuần để thực hiện việc này nếu bạn tải đúng tệp cấu hình để kết nối với cơ sở dữ liệu của mình.
Một điều cần lưu ý nếu bộ nhớ là quý giá là tập lệnh / nhân vật chạy (hoặc tác vụ Rake phụ thuộc vào 'môi trường') sẽ tải toàn bộ môi trường Rails. Nếu bạn chỉ cần chèn một số bản ghi vào cơ sở dữ liệu, điều này sẽ sử dụng bộ nhớ mà bạn không thực sự phải làm. Nếu bạn viết kịch bản của riêng bạn, bạn có thể tránh điều này. Tôi chưa thực sự cần phải làm điều này, nhưng tôi đang xem xét nó.
Sử dụng Craken (công việc cron centric centre)
Tôi sử dụng nền tảng.
http://backgroundrb.rubyforge.org/
Tôi sử dụng nó để chạy các tác vụ theo lịch trình cũng như các tác vụ mất quá nhiều thời gian cho mối quan hệ máy khách / máy chủ bình thường.
Đây là cách tôi đã thiết lập các nhiệm vụ cron của mình. Tôi có một cái để tạo các bản sao lưu hàng ngày của cơ sở dữ liệu SQL (sử dụng rake) và một cái khác để hết hạn bộ nhớ cache mỗi tháng một lần. Bất kỳ đầu ra nào được ghi vào một tệp nhật ký / cron_log. Crontab của tôi trông như thế này:
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
Tác vụ cron đầu tiên thực hiện sao lưu db hàng ngày. Nội dung của cron_t Nhiệm vụ như sau:
/usr/local/bin/rake db:backup RAILS_ENV=production; date; echo "END OF OUTPUT ----";
Tác vụ thứ hai được thiết lập sau đó và sử dụng tập lệnh / nhân vật để hết hạn bộ nhớ cache mỗi tháng một lần (lib / tháng_cron.rb):
#!/usr/local/bin/ruby
# Expire challenge cache
Challenge.force_expire_cache
puts "Expired cache for Challenges (Challenge.force_expire_cache) #{Time.now}"
Tôi đoán tôi có thể sao lưu cơ sở dữ liệu theo một cách khác nhưng cho đến nay nó hoạt động với tôi :)
Các đường dẫn đến cào và ruby có thể khác nhau trên các máy chủ khác nhau. Bạn có thể thấy họ đang ở đâu bằng cách sử dụng:
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
Sử dụng một cái gì đó Sidekiq hoặc Resque là một giải pháp mạnh mẽ hơn nhiều. Cả hai đều hỗ trợ thử lại công việc, độc quyền với khóa REDIS, giám sát và lập lịch.
Hãy nhớ rằng Resque là một dự án đã chết (không được duy trì tích cực), vì vậy Sidekiq là một cách thay thế tốt hơn. Nó cũng hiệu quả hơn: Sidekiq điều hành một số công nhân trong một quy trình đa luồng duy nhất trong khi Resque điều hành mỗi công nhân trong một quy trình riêng biệt.
Gần đây tôi đã tạo ra một số công việc định kỳ cho các dự án tôi đang làm.
Tôi thấy rằng Đồng hồ đá quý rất hữu ích.
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
Bạn thậm chí có thể lên lịch công việc nền của bạn bằng cách sử dụng đá quý này. Để biết tài liệu và trợ giúp thêm, hãy tham khảo https://github.com/Rykian/clockwork
bạn có thể sử dụng resque
và resque-schedular
đá quý để tạo cron, điều này rất dễ thực hiện.
Một khi tôi đã phải đưa ra quyết định tương tự và tôi thực sự hạnh phúc với quyết định đó ngày hôm nay. Sử dụng bộ lập lịch resque vì không chỉ một redis riêng biệt sẽ tải tải từ db của bạn, bạn cũng sẽ có quyền truy cập vào nhiều plugin như resque-web cung cấp giao diện người dùng tuyệt vời. Khi hệ thống của bạn phát triển, bạn sẽ có nhiều nhiệm vụ hơn để lên lịch để bạn có thể kiểm soát chúng từ một nơi duy nhất.
Có lẽ cách tốt nhất để làm điều đó là sử dụng rake để viết các tác vụ bạn cần và chỉ cần thực hiện nó thông qua dòng lệnh.
Bạn có thể xem một video rất hữu ích tại railscasts
Ngoài ra hãy xem tài nguyên khác này:
Tôi không thực sự chắc chắn, tôi đoán nó phụ thuộc vào nhiệm vụ: tần suất chạy, mức độ phức tạp và mức độ liên lạc trực tiếp với dự án đường ray là cần thiết, v.v ... Tôi đoán nếu chỉ có "Một cách tốt nhất" để làm gì đó , sẽ không có nhiều cách khác nhau để làm điều đó.
Ở công việc cuối cùng của tôi trong một dự án Rails, chúng tôi cần phải tạo một thư mời hàng loạt (thư mời khảo sát, không gửi thư rác) để gửi thư theo kế hoạch bất cứ khi nào máy chủ có thời gian. Tôi nghĩ rằng chúng tôi sẽ sử dụng các công cụ daemon để chạy các tác vụ cào mà tôi đã tạo.
Thật không may, công ty chúng tôi có một số vấn đề về tiền và đã bị đối thủ chính "mua" nên dự án chưa bao giờ được hoàn thành, vì vậy tôi không biết cuối cùng chúng tôi sẽ sử dụng cái gì.
Tôi sử dụng tập lệnh để chạy cron, đó là cách tốt nhất để chạy cron. Đây là một số ví dụ cho cron,
Mở CronTab -> sudo crontab -e
Và dán dòng Bellow:
00 00 * * * wget https: // your_host / some_API_end_point
Đây là một số định dạng cron, sẽ giúp bạn
::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.
Hy vọng điều này sẽ giúp bạn :)