Pergunta

Qual é a melhor maneira de executar tarefas agendadas em um ambiente Rails? Script / corredor? Rake?

Foi útil?

Solução

Eu estou usando a abordagem de rake (como apoiado por heroku )

Com um arquivo chamado lib / tarefas / cron.rake ..

task :cron => :environment do
  puts "Pulling new requests..."
  EdiListener.process_new_messages
  puts "done."
end

Para executar a partir da linha de comando, este é apenas "cron ancinho". Este comando pode então ser colocado no agendador cron sistema operacional / tarefa como desejado.

Atualizar esta é uma questão bastante antiga e resposta! Algumas novas informações:

  • o serviço heroku cron I referenciada desde então tem sido substituído por Heroku Scheduler
  • para tarefas frequentes (esp. Onde você quer evitar o custo Rails ambiente de arranque) a minha abordagem preferida é usar o cron sistema para chamar um script que irá (a) picar uma API webhook seguro / privada para invocar a tarefa desejada no fundo ou (b) enfileirar diretamente uma tarefa no sistema de filas de escolha

Outras dicas

Eu usei o extremamente popular Sempre em projetos que dependem fortemente das tarefas agendadas, e é ótimo . Ela dá-lhe uma agradável DSL para definir as tarefas agendadas em vez de ter que lidar com o formato crontab. Desde o README:

Sempre que é uma jóia Ruby que fornece uma sintaxe clara para escrever e implantação agendador de tarefas.

Exemplo do 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

Em nosso projeto usado pela primeira vez sempre jóia, mas confrontado com alguns problemas.

Em seguida, mudou para RUFUS SCHEDULER gem, que acabou para ser muito fácil e confiável para agendamento de tarefas em Rails.

Nós tê-lo usado para enviar e-mails semanais e diárias, e até mesmo para a execução de algumas tarefas rake periódicos ou qualquer método.

O código usado neste processo é assim:

    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

Para saber mais: https://github.com/jmettraux/rufus-scheduler

Assumindo as suas tarefas não demorar muito tempo para ser concluído, basta criar um novo controlador com uma ação para cada tarefa. Implementar a lógica da tarefa como código do controlador, Em seguida, criar um cron no nível de sistema operacional que utiliza o wget para invocar a URL deste controlador e ação nos intervalos de tempo apropriados. As vantagens deste método são que você:

  1. tenham pleno acesso a todas as suas Rails objetos assim como em um controlador normal.
  2. É possível desenvolver e testar assim como você faz ações normais.
  3. Pode também invocar o seu tarefas adhoc de uma página web simples.
  4. Não consuma mais memória, disparando-se de rubi adicional / trilhos processos.

O problema com sempre (e cron) é que ele recarrega o ambiente rails cada vez que é executado, que é um problema real quando as tarefas são freqüentes ou ter um monte de trabalho de inicialização para fazer. Eu tive problemas na produção por causa deste e deve avisá-lo.

Rufus programador faz isso por mim ( https://github.com/jmettraux/rufus-scheduler )

Quando tenho trabalhos longos para executar, eu usá-lo com delayed_job ( https://github.com/collectiveidea/delayed_job )

Espero que isso ajude!

Eu sou um grande fã de resque / resque programador . Você não pode apenas executar repetindo cron-como tarefas, mas também tarefas em horários específicos. A desvantagem é que ele requer um servidor Redis.

tarefas

script / corredor e ancinho são perfeitamente bem para executar como tarefas agendadas.

Aqui está uma coisa muito importante que você deve lembrar ao executar tarefas agendadas. Eles provavelmente não será chamado a partir do diretório raiz do seu aplicativo. Todas as suas requer para arquivos (ao contrário de bibliotecas) este meio deve ser feito com o caminho explícito: por exemplo, File.dirname (__ FILE__) + "/ other_file". Isso também significa que você tem que saber como chamá-los explicitamente de outro diretório: -)

Verifique se os seus suportes de código a ser executado a partir de outro diretório com

# 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

Além disso, tarefas agendadas, provavelmente, não correm como você, por isso não depende de qualquer atalho que você colocar em .bashrc. Mas isso é apenas uma ponta cron padrão; -)

Isso é interessante ninguém mencionou o Sidetiq . É bom disso, se você já está usando Sidekiq.

Sidetiq fornece uma API simples para definir trabalhadores recorrentes para Sidekiq.

Job será parecido com este:

class MyWorker
  include Sidekiq::Worker
  include Sidetiq::Schedulable

  recurrence { hourly.minute_of_hour(15, 45) }

  def perform
    # do stuff ...
  end
end

Ambos irão funcionar bem. Eu costumo usar o script / corredor.

Aqui está um exemplo:

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

Você também pode escrever um script puro-Ruby para fazer isso se você carregar os arquivos de configuração corretas para se conectar ao seu banco de dados.

Uma coisa a ter em mente se a memória é precioso é que script / corredor (ou uma tarefa Rake que depende de 'ambiente') irá carregar todo o ambiente Rails. Se você só precisa inserir alguns registros no banco de dados, isso vai usar a memória que você realmente não precisa. Se você escrever seu próprio script, você pode evitar isso. Eu realmente não tenho necessidade de fazer isso ainda, mas eu estou considerando isso.

Use Craken (ancinho tarefas agendadas centric)

Eu uso backgroundrb.

http://backgroundrb.rubyforge.org/

Eu usá-lo para executar tarefas agendadas, bem como as tarefas que levam muito tempo para o relacionamento normal cliente / servidor.

Aqui está como eu tenho a configuração minhas tarefas cron. Eu tenho um para fazer backups diários do banco de dados SQL (usando ancinho) e outra para expirar cache de uma vez por mês. Qualquer saída é registrada em um log file / cron_log. Meus olhares crontab como esta:

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

A primeira tarefa cron faz backups db diárias. O conteúdo do cron_tasks são os seguintes:

/usr/local/bin/rake db:backup RAILS_ENV=production; date; echo "END OF OUTPUT ----";

A segunda tarefa foi instalado mais tarde e usos script / corredor para expirar cache de uma vez por mês (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}"

Eu acho que eu poderia banco de dados de backup de alguma outra maneira, mas até agora ele funciona para mim:)

caminhos para ancinho e rubi pode variar em diferentes servidores. Você pode ver onde eles estão usando:

whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake

Usando algo Sidekiq ou Resque é uma solução muito mais robusta. Ambos apoio repetindo empregos, exclusividade com um bloqueio REDIS, monitoramento e agendamento.

Tenha em mente que Resque é um projeto morto (não mantido ativamente), de modo Sidekiq é uma maneira melhor alternativa. É também mais performance:. Sidekiq executa vários trabalhadores em um único processo, multithread enquanto Resque corre cada trabalhador em um processo separado

Tenho recentemente criado algumas tarefas agendadas para os projectos que tenho vindo a trabalhar.

Eu achei que o gem Clockwork muito útil.

require 'clockwork'

module Clockwork
  every(10.seconds, 'frequent.job')
end

Você pode até mesmo agendar o seu trabalho de fundo usando esta jóia. Para documentação e mais ajuda referem https://github.com/Rykian/clockwork

Uma vez que eu tive que tomar a mesma decisão e eu estou realmente feliz com essa decisão hoje. Use resque programador porque não apenas Redis separadas vai tirar a carga do seu db, você também terá acesso a muitos plugins como resque-web que fornece uma interface de usuário grande. Como o sistema se desenvolve, você terá mais e mais tarefas a programação de modo que você será capaz de controlá-los a partir de um único lugar.

Você pode usar gem resque e resque-shheduler para a criação de crons, isso é muito fácil de fazer.

https://github.com/resque/resque

https://github.com/resque/resque-scheduler

Provavelmente a melhor maneira de fazer isso é usando o ancinho para escrever as tarefas que você precisa ea apenas executá-lo via linha de comando.

Você pode ver um vídeo href="http://railscasts.com/episodes/66-custom-rake-tasks" muito útil em Railscasts

Também dê uma olhada neste outros recursos:

relógio gem e ele funciona muito bem para mim. Há também gem clockworkd que permite que um script para ser executado como um daemon.

Eu não estou realmente certo, eu acho que depende da tarefa: quantas vezes a correr, quanto complicado e quanto a comunicação direta com os trilhos projeto é necessário etc. Eu acho que se houvesse apenas "One Best Way " para fazer alguma coisa, não haveria tantas maneiras diferentes de fazê-lo.

No meu último emprego em um projeto Rails, que precisávamos para fazer uma mailer convite lote (convites para pesquisas, não spam) que deverá enviar os e-mails planejados sempre que o servidor teve tempo. Eu acho que nós estávamos indo para usar daemon ferramentas para executar as tarefas rake que eu tinha criado.

Infelizmente, a nossa empresa teve alguns problemas de dinheiro e foi "comprada" pelo principal rival para que o projeto nunca foi concluído, então eu não sei o que acabaria por ter usado.

I Use script para executar cron, que é a melhor maneira de executar um cron. Aqui estão algumas exemplo para cron,

Open crontab -> sudo crontab -e

e cole linhas a seguir:

00 00 * * * wget https: // your_host / some_API_end_point

Aqui está algum formato cron, irá ajudá-lo

::CRON FORMAT::

table formato cron

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. 

Espero que isso irá ajudá-lo:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top