Cron Jobs and Rails

Cron

Nếu bạn đang đọc bài viết này, có thể là vì bạn đã nghe nói về công việc của cron, các tác vụ cron hoặc crontab. Cron là một phần của phần mềm được viết cho các hệ điều hành kiểu * nix để giúp lập kế hoạch các nhiệm vụ định kỳ. Bạn có thể sử dụng cron để lập lịch các hành động định kỳ nhất định trong ứng dụng Rails của bạn, chẳng hạn như kiểm tra các tài khoản đã hết hạn hoặc xóa hết các phiên hết hạn từ cơ sở dữ liệu của bạn.

Khá dễ dàng để bắt đầu làm việc với cron jobs. Bạn có thể bắt đầu chỉnh sửa các nhiệm vụ cron bằng cách sử dụng lệnh crontab:

crontab -e

Thao tác này sẽ mở một tệp tin văn bản trong trình soạn thảo mặc định trong terminal của bạn (có thể là vim hoặc nano). Bạn có thể thay đổi trình soạn thảo được sử dụng bằng tiền tố lệnh crontab với một điều chỉnh cho biến EDITOR:

EDITOR=nano crontab -e

Hãy nhớ rằng các tác vụ theo lịch trình của bạn sẽ được chạy như người dùng khi bạn gọi crontab.

Khi bạn đã vào trình biên tập, bạn có thể bắt đầu tạo và chỉnh sửa các tác vụ cron. Để lên kế hoạch cho một tác vụ, bạn cần phải định nghĩa khi nhiệm vụ sẽ chạy, sau đó định nghĩa lệnh để kích hoạt nhiệm vụ đó. Cú pháp lập lịch trình có năm phần, cách nhau bằng khoảng trống (sơ đồ lấy từ drupal.org):

# +---------------- minute (0 - 59)
# |  +------------- hour (0 - 23)
# |  |  +---------- day of month (1 - 31)
# |  |  |  +------- month (1 - 12)
# |  |  |  |  +---- day of week (0 - 6) (Sunday=0)
# |  |  |  |  |
  *  *  *  *  *  command to be executed

Theo thứ tự sắp xếp này, mỗi dấu * là một ký tự đại diện cho phút, giờ, ngày trong tháng, tháng và ngày trong tuần. Một khi bạn có lịch trình của bạn được xác định, bạn có thể làm theo nó với bất kỳ lệnh bash hợp lệ nào:

# Every day at midnight and noon, quiely retrieve index.html from example.com, # using wget:
0 0,12 * * * /usr/bin/wget -O -q -t 1 http://example.com/index.html

# Same task, but just once every day
@daily /usr/bin/wget -O -q -t 1 http://example.com/index.html

Chạy Rails Application Code thông qua Cron

Rake Tasks từ Cron

Để chạy một nhiệm vụ rake hiện tại, bạn có thể thay đổi thư mục của bạn vào gốc ứng dụng của bạn, sau đó gọi công việc rake:

0 0 * * * cd /my/app/root && /path/to/bundle exec rake some_task

Không cần phải giới hạn rake tasks của bạn trong những lệnh đã có sẵn ở Rails hoặc bất cứ đá quý bạn sử dụng. Bạn có thể tự định nghĩa 1 rake task của riêng bạn và sử dụng nó trong cron jobs của bạn. Bạn có thể tìm thêm thông tin về cách viết các rake task của riêng bạn ở đây.

Runners

Một cách khác để chạy mã trong ứng dụng Rails trực tiếp từ cron bằng cách sử dụng Rails runners. Tất cả những gì bạn phải làm là gọi rails runner "ruby code"

0 * * * * cd /my/app/root && /path/to/bundle exec rails runner -e production "Model.long_running_method"

Gem Whenever

Một trong những khó khăn khi sử dụng cron là nó là bạn sẽ lúng túng để duy trì và lưu trữ các công việc cron của bạn. Cú pháp cũng có thể trở nên cồng kềnh với người mới bắt đầu, và rất dễ mắc phải những sai lầm trong việc thiết lập lịch biểu và đường dẫn thực thi của bạn. Một cách để vượt qua những khó khăn này là sử dụng gem Whenever. Add gem 'whenever', require: false vào Gemfile và chạy bundle install. Sau đó, trong thư mục gốc của ứng dụng, hãy chạy lệnh sau:

bundle exec wheneverize

Điều này sẽ thêm một tập tin lịch trình vào thư mục config của bạn (config / schedule.rb). Tập tin này là nơi bạn thiết lập nhiệm vụ theo lịch trình của mình. Bạn có thể sử dụng lập lịch cron thường xuyên, hoặc bạn có thể sử dụng một DSL tiện dụng hơn để lên kế hoạch. Các ví dụ sau đây lấy từ README.md của gem:

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

every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
  runner "SomeModel.ladeeda"
end

every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
  runner "Task.do_something_great"
end

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
every :day, :at => '12:20am', :roles => [:app] do
  rake "app_server:task"
end

Một khi bạn đã thiết lập các nhiệm vụ theo lịch trình của bạn trong config/schedule.rb, bạn vẫn cần phải áp dụng chúng vào crontab của bạn. Từ termial, sử dụng lệnh whenever để cập nhật crontab của bạn:

# Thay đổi thư mục ứng dụng của bạn.
cd /my/app

# Xem config/schedule.rb được chuyển đổi thành cron syntax
bundle exec whenever

# Update crontab
bundle exec whenever -i

# Ghi đè toàn bộ crontab (hãy cẩn thận với cái này!)
bundle exec whenever -w

# Xem tất cả các tùy chọn cho lệnh whenever
bundle exec whenever -h

Có 1 capistrano extension cho whenever, vì vậy nếu bạn sử dụng capistrano để deploy app của bạn, hãy chắc chắn rằng bạn đã sự dụng nó.

Tham khảo

https://launchschool.com/blog/cron-jobs-and-rails https://github.com/javan/whenever