cron, todos os problemas de ram minuto

3

Eu tenho um cronjob que executa o PHP em um arquivo wordpress cron.php. É usado principalmente para agendar post e acredito que pode atualizar o cache.

Eu corro o cron job a cada minuto. Eu verifiquei o ps frequentemente e vejo DOIS instâncias do PHP executando o cron.php. Agora isso é desnecessário porque a execução de uma instância fará tudo o que for necessário. Eu tenho outro trabalho que verifica ram e, por vezes, duas instâncias de viagem-lo (eu espero uma alta quantidade de memória RAM disponível em todos os momentos, eu posso abaixá-lo, mas eu não quero). Eu dificilmente acredito que um trabalho possa levar mais de um minuto (embora seja possível).

Como faço para executar um trabalho, mas não se o processo já existe? Eu não acho que o código PHP em si pode verificar a menos que se conecta / usa o db? Existe um comando cron que eu possa usar? Eu não quero matar uma instância se for um > 1 minuto. Apenas não crie novos.

    
por Jeff Schaller 02.04.2012 / 19:11

3 respostas

1

Aqui está uma solução simples de script; você provavelmente pode fazer o mesmo no script cron.php. Na verdade, ele verifica se há processos que duram muito tempo; para um sistema automatizado, esta é provavelmente uma boa ideia.

#!/bin/bash

# Exit if process is already running
if test -e /tmp/wordpress-job.pid; then
  # Check if the pid that was stored in /tmp/wordpress-job.pid does exist
  if ps ax -o pid= | grep $(cat /tmp/wordpress-job.pid ) &> /dev/null; then
    exit 0
  fi
fi

# Create the file that marks this process as running
echo $$ > /tmp/wordpress-job.pid

# Some extra security check to prevent the pid file
# to survive.
trap "rm -f /tmp/wordpress-job.pid" EXIT TERM INT HUP 

# Start the long-running process in the background
sleep 3600 & # long-running process

# Sleep some time before trying to kill that process
sleep 300

# Kill job if it takes longer than it should
kill %1

# Delete the file that marks this process as running
rm -f /tmp/wordpress-job.pid

Você tem que substituir o "sleep 3600" pela sua linha de comando do php, e mudar o 300 abaixo para o tempo máximo que o seu script deve ter permissão para rodar.

    
por 02.04.2012 / 19:35
0

Faça sua entrada crontab rodar isto:

if mv /var/run/my-php-job.pending /var/run/my-php-job.running 2>/dev/null; then
  echo $$ >|/var/run/my-php-job.running   # optional
  … # run the job
  : >|/var/run/my-php-job.running         # optional
  mv /var/run/my-php-job.running /var/run/my-php-job.pending
fi

Coloque isso em uma entrada @reboot crontab:

rm -f /var/run/my-php-job.running
touch /var/run/my-php-job.pending

O nome do arquivo serve como um bloqueio. Embora seja .running , há um trabalho em execução e o próximo trabalho não será iniciado. Quando é .pending , o trabalho em execução é iniciado e alterna para .running .

Se você incluir as linhas opcionais, o ID do processo do shell será gravado no arquivo .running , para fins de investigação, se um trabalho ficar preso. Um arquivo de log faria isso redundante.

Se o shell executando o trabalho travar (o que é improvável, e somente riscos acontecerão se alguém deliberadamente o matar ou em uma condição de pouca memória, o arquivo de travamento ficará preso em .running . (Se o trabalho em si falhar, não há problema.) Você pode detectar a morte súbita de um script anterior, mas é significativamente mais difícil.

    
por 03.04.2012 / 01:58
0

Existem utilitários especiais para evitar execuções paralelas: flock in util-linux, lockf em sistemas BSD, shlock no NetBSD e com pacotes INN e cnews.

Com o caso mais provável (Linux), chame algo semelhante a:

flock -w 60 /somedir/lockfile cron.php

Receitas em outras respostas são alternativas de rebanho cultivadas em casa e são úteis somente em caso de ausência de tal ferramenta.

OTOH você pode lidar com esse bloqueio em seu programa diretamente, mas você deve repetir todos os detalhes com cuidado, caso contrário, você pode criar condições de corrida.

    
por 03.04.2012 / 09:19

Tags