วิธีที่ดีที่สุดในการใช้งานที่กำหนดเวลาไว้ในสภาพแวดล้อม Rails คืออะไร Script / วิ่ง? คราด? ฉันต้องการทำงานทุกสองสามนาที
วิธีที่ดีที่สุดในการใช้งานที่กำหนดเวลาไว้ในสภาพแวดล้อม Rails คืออะไร Script / วิ่ง? คราด? ฉันต้องการทำงานทุกสองสามนาที
คำตอบ:
ฉันใช้วิธีการคราด (ตามที่herokuสนับสนุน)
ด้วยไฟล์ชื่อ lib / task / cron.rake ..
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
ในการดำเนินการจากบรรทัดคำสั่งนี่เป็นเพียง "rake cron" คำสั่งนี้สามารถวางบนระบบปฏิบัติการ cron / task scheduler ได้ตามต้องการ
อัปเดตนี่เป็นคำถามและคำตอบที่ค่อนข้างเก่า! ข้อมูลใหม่บางส่วน:
load "#{Rails.root}/lib/tasks/cron.rake"
และrake cron
แต่มี NameError: ตัวแปรท้องถิ่นไม่ได้กำหนดหรือวิธี `cron สำหรับหลัก: วัตถุ
:environment
พึ่งพา เรามีโปรแกรมที่มีทางรถไฟหนักมากที่ใช้เวลานานในการเริ่มต้นขึ้นคราดของเราจะเรียกว่าทุกนาทีและใช้ทรัพยากรมากขึ้นเริ่มต้นขึ้นสภาพแวดล้อมทางรถไฟที่ดำเนินการงาน ฉันชอบที่จะมีอยู่แล้วเริ่มต้นขึ้นสภาพแวดล้อมทางรถไฟที่จะเรียกว่าผ่าน cron ที่จะต้องมีบางสิ่งบางอย่างระหว่างควบคุมวิธีการและสภาพแวดล้อมในการเสาะหาหนึ่ง
ฉันเคยใช้งานเมื่อใดก็ตามที่เป็นที่นิยมอย่างมากในโครงการที่ต้องพึ่งพางานที่กำหนดไว้มากและมันยอดเยี่ยม มันช่วยให้คุณมี DSL ที่ดีในการกำหนดงานที่กำหนดไว้ของคุณแทนที่จะต้องจัดการกับรูปแบบ crontab จาก README:
เมื่อใดก็ตามที่เป็นอัญมณีทับทิมที่ให้บริการไวยากรณ์ที่ชัดเจนสำหรับการเขียนและการปรับใช้งาน cron
ตัวอย่างจาก 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ซึ่งกลายเป็นเรื่องง่ายและน่าเชื่อถือสำหรับการจัดตารางงานใน 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
หากต้องการเรียนรู้เพิ่มเติม: https://github.com/jmettraux/rufus-scheduler
สมมติว่างานของคุณใช้เวลาไม่นานในการทำให้เสร็จสมบูรณ์เพียงแค่สร้างคอนโทรลเลอร์ใหม่พร้อมแอ็คชั่นสำหรับแต่ละงาน ใช้ตรรกะของงานเป็นรหัสควบคุมจากนั้นตั้งค่า cronjob ที่ระดับระบบปฏิบัติการที่ใช้ wget เพื่อเรียก URL ของตัวควบคุมและการกระทำนี้ในช่วงเวลาที่เหมาะสม ข้อดีของวิธีนี้คือคุณ:
งาน script / runner และ rake นั้นสมบูรณ์แบบที่จะทำงานเป็น cron
นี่คือสิ่งสำคัญอย่างหนึ่งที่คุณต้องจำไว้เมื่อเรียกใช้งาน cron พวกเขาอาจจะไม่ถูกเรียกจากไดเรกทอรีรากของแอปของคุณ ซึ่งหมายความว่าสิ่งที่คุณต้องการสำหรับไฟล์ทั้งหมด (ตรงข้ามกับไลบรารี) ควรทำด้วยพา ธ ที่ชัดเจน: เช่น 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) ก็คือมันจะโหลดสภาพแวดล้อมทางรถไฟทุกครั้งที่มีการดำเนินการซึ่งเป็นปัญหาจริงเมื่องานของคุณเป็นประจำหรือมีงานเริ่มต้นจำนวนมากที่ต้องทำ ฉันมีปัญหาในการผลิตเนื่องจากสิ่งนี้และต้องเตือนคุณ
ตัวจัดกำหนดการ Rufus ทำเพื่อฉัน ( https://github.com/jmettraux/rufus-scheduler )
เมื่อฉันมีงานที่ต้องใช้เวลานานฉันจะใช้มันกับ delay_job ( https://github.com/collectiveidea/delayed_job )
ฉันหวังว่านี่จะช่วยได้!
ที่น่าสนใจไม่มีใครกล่าวถึงSidetiq มันเป็นการเพิ่มเติมที่ดีถ้าคุณใช้ Sidekiq อยู่แล้ว
Sidetiq จัดเตรียม API อย่างง่ายสำหรับการกำหนดคนทำงานประจำสำหรับ Sidekiq
งานจะมีลักษณะเช่นนี้:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
ทั้งสองจะทำงานได้ดี ฉันมักจะใช้สคริปต์ / นักวิ่ง
นี่คือตัวอย่าง:
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 เพื่อทำสิ่งนี้หากคุณโหลดไฟล์ config ที่เหมาะสมเพื่อเชื่อมต่อกับฐานข้อมูลของคุณ
สิ่งหนึ่งที่ต้องระลึกไว้เสมอว่าหน่วยความจำมีค่าคือ script / Runner (หรืองาน Rake ที่ขึ้นอยู่กับ 'environment') จะโหลดสภาพแวดล้อมของ Rails ทั้งหมด หากคุณต้องการแทรกระเบียนลงในฐานข้อมูลจะใช้หน่วยความจำที่คุณไม่จำเป็นต้องใช้จริงๆ หากคุณเขียนสคริปต์ของคุณเองคุณสามารถหลีกเลี่ยงสิ่งนี้ ฉันยังไม่จำเป็นต้องทำสิ่งนี้ แต่ฉันกำลังพิจารณาอยู่
ใช้Craken (rake centric cron jobs)
ฉันใช้ backgroundrb
http://backgroundrb.rubyforge.org/
ฉันใช้เพื่อเรียกใช้งานตามกำหนดเวลารวมถึงงานที่ใช้เวลานานเกินไปสำหรับความสัมพันธ์ระหว่างลูกค้า / เซิร์ฟเวอร์ปกติ
นี่คือวิธีการตั้งค่างาน cron ของฉัน ฉันมีหนึ่งที่จะทำการสำรองข้อมูลรายวันของฐานข้อมูล SQL (ใช้ rake) และอื่น ๆ เพื่อหมดอายุแคชเดือนละครั้ง เอาต์พุตใด ๆ ถูกบันทึกไว้ในล็อกไฟล์ / 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 ----";
ภารกิจที่สองถูกตั้งค่าในภายหลังและใช้สคริปต์ / นักวิ่งเพื่อหมดอายุแคชเดือนละครั้ง (lib / month_cron.rb):
#!/usr/local/bin/ruby
# Expire challenge cache
Challenge.force_expire_cache
puts "Expired cache for Challenges (Challenge.force_expire_cache) #{Time.now}"
ฉันเดาว่าฉันสามารถสำรองฐานข้อมูลด้วยวิธีอื่นได้ แต่จนถึงตอนนี้มันใช้งานได้สำหรับฉัน :)
เส้นทางที่จะเสาะหาและทับทิมสามารถแตกต่างกันบนเซิร์ฟเวอร์ที่แตกต่างกัน คุณสามารถดูว่าพวกเขาอยู่ที่ไหนโดยใช้:
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
การใช้สิ่งที่ Sidekiq หรือ Resque เป็นทางออกที่แข็งแกร่งกว่า พวกเขาทั้งสองสนับสนุนงานลองใหม่ความพิเศษกับล็อค REDIS การตรวจสอบและการกำหนดเวลา
โปรดทราบว่า Resque เป็นโครงการที่ตายแล้ว (ไม่ได้รับการบำรุงรักษาอย่างแข็งขัน) ดังนั้น Sidekiq จึงเป็นทางเลือกที่ดีกว่า นอกจากนี้ยังมีประสิทธิภาพมากกว่า: Sidekiq ทำงานหลายคนในกระบวนการมัลติเธรดเดียวในขณะที่ Resque เรียกใช้แต่ละคนงานในกระบวนการแยกต่างหาก
ฉันเพิ่งสร้างงาน cron บางอย่างสำหรับโครงการที่ฉันทำงานอยู่
ฉันพบว่าClockworkอัญมณีมีประโยชน์มาก
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
คุณสามารถกำหนดเวลางานพื้นหลังของคุณโดยใช้อัญมณีนี้ สำหรับเอกสารและความช่วยเหลือเพิ่มเติมอ้างอิงhttps://github.com/Rykian/clockwork
คุณสามารถใช้resque
และresque-schedular
อัญมณีสำหรับการสร้าง cron นี่เป็นเรื่องง่ายมากที่จะทำ
เมื่อฉันต้องทำการตัดสินใจแบบเดียวกันและฉันมีความสุขมากกับการตัดสินใจในวันนี้ ใช้ตัวกำหนดตารางเวลา resqueเนื่องจากไม่เพียง แต่ redis ที่แยกจากกันจะนำภาระออกจาก db ของคุณคุณยังสามารถเข้าถึงปลั๊กอินจำนวนมากเช่น resque-web ซึ่งมีส่วนต่อประสานผู้ใช้ที่ยอดเยี่ยม ในขณะที่ระบบของคุณพัฒนาคุณจะมีงานมากขึ้นในการกำหนดเวลาดังนั้นคุณจะสามารถควบคุมงานได้จากที่เดียว
อาจเป็นวิธีที่ดีที่สุดในการใช้ rake เพื่อเขียนงานที่คุณต้องการและเพียงแค่รันมันผ่านทางบรรทัดคำสั่ง
คุณสามารถดูวิดีโอที่มีประโยชน์มากได้ที่ railscasts
ดูทรัพยากรอื่น ๆ ด้วย:
ฉันใช้อัญมณีนาฬิกาและมันทำงานได้ดีสำหรับฉัน นอกจากนี้ยังมีclockworkd
อัญมณีที่อนุญาตให้สคริปต์รันเป็น daemon
ฉันไม่แน่ใจจริง ๆ ฉันคิดว่ามันขึ้นอยู่กับงานว่าต้องวิ่งบ่อยแค่ไหนซับซ้อนเท่าไหร่และต้องมีการสื่อสารโดยตรงกับโครงการรถไฟมากแค่ไหน ฯลฯ ฉันเดาว่าถ้ามี"One Best Way"ที่จะทำบางสิ่งบางอย่าง จะไม่มีวิธีที่แตกต่างมากมายที่จะทำ
ในงานสุดท้ายของฉันในโครงการ 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.
หวังว่านี่จะช่วยคุณ :)