Como agendar trabalhos do servidor com mais inteligência do que com o cron?

15

Executo um trabalho a cada minuto para reindexar o conteúdo do meu site.

Hoje, o mecanismo de pesquisa morreu e, quando eu entrei, havia centenas de processos órfãos que haviam sido iniciados pelo cron.

Existe outra maneira de usar algum tipo de software existente que me permita executar um trabalho a cada minuto, mas que não iniciará outra instância se esse trabalho não retornar (ou seja, porque o processo do mecanismo de pesquisa falhou)?

John
fonte
4
O cron provavelmente está fazendo exatamente o que você está dizendo. Sugiro reescrever o trabalho de forma inteligente.
gparent

Respostas:

27

O problema não é realmente com o cron - é com o seu trabalho.

Você precisará que seu trabalho interaja com um bloqueio de alguma descrição. A maneira mais fácil de fazer isso é tentar criar um diretório e, se for bem-sucedido, continuar, se não sair. Quando seu trabalho terminar e sair, ele deverá remover o diretório pronto para a próxima execução. Aqui está um script para ilustrar.

#!/bin/bash

function cleanup {
    echo "Cleanup"
    rmdir /tmp/myjob.lck
}

mkdir /tmp/myjob.lck ||  exit 1
trap cleanup EXIT
echo 'Job Running'
sleep  60
exit 0

Execute isso em um terminal e, antes que os 60 segundos terminem, execute-o em outro terminal e ele sairá com o status 1. Quando o primeiro processo terminar, você poderá executá-lo a partir do segundo terminal ...

EDITAR:

Como acabei de aprender sobre o rebanho, pensei em atualizar esta resposta. O rebanho (1) pode ser mais fácil de usar. Nesse caso flock -n, pareceria apropriado, por exemplo

* * * * * /usr/bin/flock -n /tmp/myAppLock.lck /path/to/your/job   

Executaria seu trabalho a cada minuto, mas falharia se o rebanho não conseguisse obter um bloqueio no arquivo.

user9517
fonte
2
Pergunta estúpida, talvez, mas existem vantagens em usar um diretório especificamente, em vez de um arquivo comum?
gparent
9
O uso de um arquivo regular requer várias operações, verifique se ele existe, se não o cria. Isso deixa uma janela de oportunidade para outro processo criar o arquivo - confuso. O mkdir é uma operação atômica ou funciona e você obtém o 'bloqueio' ou não, pois outro processo já o possui.
user9517
Faz sentido. Bom pensamento no diretório de bloqueio também. Obrigado
John
2

Uma maneira seria fazer com que seu script reindex crie um arquivo de bloqueio para que ele possa verificar se já existe uma instância do script em execução. Você também pode adicionar algum tratamento de exceção para verificar se o mecanismo de pesquisa está em funcionamento.

Uma alternativa mais envolvida seria usar algum tipo de tarefa queuer como Resque e Resque-scheduler:

https://github.com/blog/542-introducing-resque

https://github.com/bvandenbos/resque-scheduler#readme

Há também Qu e Sidekiq:

https://github.com/bkeepers/qu

https://github.com/mperham/sidekiq

Sim, isso é tudo orientado a Ruby, mas você pode procurar por "coisas como resque" no idioma de sua escolha.

cjc
fonte
0

Outra maneira de configurar isso rapidamente é iniciar um script de shell quando a máquina é inicializada (o cron pode fazer isso com ' @reboot /path/to/my/script.sh',., Em seguida, reinicie o cron para iniciá-lo) com algo assim.

#!/bin/sh
/opt/bin/run-site-index
sleep 60
exec $0

O script continua em execução, e você iniciou apenas um - quantos podem estar em execução ao mesmo tempo - não mais do que isso. Alguns especialistas também podem verificar se o indexador está em execução e, se não estiver, reiniciar ou tentar corrigir / notificar alguém sobre o problema.

Alister Bulman
fonte
-3

Em vez de usar o cron para isso, eu criaria seu trabalho mais como um serviço que é executado em loop e dorme por 60 segundos como a última etapa, ou talvez dorme mais vezes por intervalos menores em vários pontos durante o processo para ajudar a espalhar a carga mais uniformemente.

Joel Coel
fonte
1
Isso não resolveria o problema nem seria uma melhoria do cron.
gparent
Isso resolveria o problema, porque só existe um processo que é executado sempre. Evitaria o cron completamente.
Joel Coel
Não corrige o problema se o 'serviço' não parecer se o mecanismo de pesquisa estiver em execução. A lógica de seu roteiro / trabalho é a questão. EDIT: Na verdade, você está certo, esconderia o problema de uma maneira feia.
gparent