Comment planifier les tâches serveur plus intelligemment qu'avec cron?

15

Je lance un travail toutes les minutes pour réindexer le contenu de mon site.

Aujourd'hui, le moteur de recherche est mort, et lorsque je me suis connecté, il y avait des centaines de processus orphelins qui avaient été lancés par cron.

Existe-t-il un autre moyen d'utiliser une sorte de logiciel existant qui me permettra d'exécuter un travail toutes les minutes, mais qui ne lancera pas une autre instance si ce travail ne revient pas (c'est-à-dire parce que le processus du moteur de recherche a échoué)?

John
la source
4
cron fait très probablement exactement ce que vous lui dites. Je suggère plutôt de réécrire le travail intelligemment.
gparent

Réponses:

27

Le problème n'est pas vraiment avec cron - c'est avec votre travail.

Vous devrez faire interagir votre travail avec un verrou d'une certaine description. La façon la plus simple de le faire est de tenter de créer un répertoire et, en cas de succès, de continuer, sinon de quitter. Une fois votre travail terminé et terminé, il devrait supprimer le répertoire prêt pour la prochaine exécution. Voici un script pour illustrer.

#!/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

Exécutez-le dans un terminal puis avant 60 secondes, exécutez-le dans un autre terminal, il sortira avec le statut 1. Une fois le premier processus terminé, vous pouvez l'exécuter à partir du deuxième terminal ...

ÉDITER:

Comme je viens d'apprendre le troupeau, j'ai pensé mettre à jour cette réponse. flock (1) peut être plus facile à utiliser. Dans ce cas, flock -ncela semble approprié, par exemple

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

Exécuterait votre travail toutes les minutes mais échouerait si flock ne pouvait pas obtenir un verrou sur le fichier.

user9517
la source
2
Question stupide peut-être, mais y a-t-il des avantages à utiliser un répertoire spécifiquement plutôt qu'un fichier normal?
gparent
9
L'utilisation d'un fichier normal nécessite plusieurs opérations, vérifiez s'il existe, s'il ne le crée pas. Cela laisse une fenêtre d'opportunité pour un autre processus pour créer le fichier - désordonné. Le mkdir est une opération atomique, soit il fonctionne et vous obtenez le «verrou», soit il ne l'est pas car un autre processus l'a déjà.
user9517
Logique. Bonne réflexion sur le répertoire de verrouillage aussi. Merci
John
2

Une façon serait que votre script de réindexation crée un fichier de verrouillage afin qu'il puisse vérifier s'il existe déjà une instance du script en cours d'exécution. Vous pouvez également ajouter une gestion des exceptions pour voir si le moteur de recherche est opérationnel.

Une alternative plus impliquée serait d'utiliser une sorte de file d'attente de tâches comme Resque et Resque-scheduler:

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

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

Il y a aussi Qu et Sidekiq:

https://github.com/bkeepers/qu

https://github.com/mperham/sidekiq

Oui, tout est orienté Ruby, mais vous pouvez rechercher des "choses comme resque" dans la langue de votre choix.

cjc
la source
0

Une autre façon de configurer rapidement ceci est d'avoir un script shell démarré au démarrage de la machine (cron peut le faire avec ' @reboot /path/to/my/script.sh',. Puis redémarrez le cron pour le démarrer) avec quelque chose comme ça.

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

Le script continue de fonctionner, et vous n'en avez démarré qu'un - c'est le nombre qui pourrait être exécuté en même temps - pas plus que cela. Certains éléments intelligents peuvent également vérifier si l'indexeur est en cours d'exécution et, dans le cas contraire, redémarrer ou sinon essayer de résoudre / informer quelqu'un du problème.

Alister Bulman
la source
-3

Au lieu d'utiliser cron pour cela, je construirais davantage votre travail en tant que service qui s'exécute en boucle et dort pendant 60 secondes comme dernière étape, ou peut-être dort plus souvent pour de plus petits intervalles à différents moments du processus pour aider à répartir la charge plus uniformément.

Joel Coel
la source
1
Cela ne résoudrait pas le problème et ne constituerait pas une amélioration par rapport à cron.
gparent
Cela résoudrait le problème, car il n'y a alors qu'un seul processus qui s'exécute. Cela contournerait complètement le cron.
Joel Coel
Il ne résout pas le problème si le «service» ne regarde pas si le moteur de recherche est en cours d'exécution. La logique de son script / travail est le problème. EDIT: En fait, vous avez quelque peu raison, cela cacherait le problème d'une manière laide.
gparent