Wie können Serverjobs intelligenter als mit cron geplant werden?

15

Ich führe jede Minute einen Job aus, um den Inhalt meiner Website neu zu indizieren.

Heute ist die Suchmaschine gestorben, und als ich mich anmeldete, gab es Hunderte von verwaisten Prozessen, die von cron gestartet wurden.

Gibt es eine andere Möglichkeit, eine vorhandene Software zu verwenden, mit der ich einen Auftrag jede Minute ausführen kann, die jedoch keine weitere Instanz startet, wenn dieser Auftrag nicht zurückgegeben wird (z. B. weil der Suchmaschinenprozess fehlgeschlagen ist)?

John
quelle
4
cron tut höchstwahrscheinlich genau das, was Sie sagen. Ich empfehle stattdessen, den Job intelligent umzuschreiben.
gparent

Antworten:

27

Das Problem ist nicht wirklich mit cron - es ist mit deinem Job.

Sie müssen Ihren Job mit einer Sperre einer Beschreibung interagieren lassen. Am einfachsten ist es, wenn Sie versuchen, ein Verzeichnis zu erstellen. Wenn dies erfolgreich ist, fahren Sie fort, wenn Sie es nicht beenden. Wenn Ihr Job beendet und beendet ist, sollte er das Verzeichnis entfernen, das für die nächste Ausführung bereit ist. Hier ist ein Skript zur Veranschaulichung.

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

Führen Sie dies in einem Terminal aus, bevor 60 Sekunden vergangen sind. Führen Sie es in einem anderen Terminal aus. Es wird mit dem Status 1 beendet. Sobald der erste Prozess beendet ist, können Sie es vom zweiten Terminal aus ausführen.

BEARBEITEN:

Als ich gerade von Flock erfuhr, dachte ich, ich würde diese Antwort aktualisieren. Herde (1) ist möglicherweise einfacher zu handhaben. In diesem Fall flock -nerscheint z

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

Würde Ihren Job jede Minute ausführen, würde aber fehlschlagen, wenn Flock keine Sperre für die Datei erhalten könnte.

user9517 supportedGoFundMonica
quelle
2
Eine blöde Frage, aber gibt es Vorteile, wenn man ein bestimmtes Verzeichnis anstelle einer normalen Datei verwendet?
gparent
9
Die Verwendung einer regulären Datei erfordert mehrere Vorgänge. Überprüfen Sie, ob sie vorhanden ist, und erstellen Sie sie anschließend nicht. Dies gibt einem anderen Prozess die Möglichkeit, die Datei zu erstellen - chaotisch. Das mkdir ist eine atomare Operation, die entweder funktioniert und Sie die 'Sperre' erhalten, oder nicht, wie es ein anderer Prozess bereits hat.
user9517 supportedGoFundMonica
Macht Sinn. Gutes Denken auch im Sperrverzeichnis. Vielen Dank
John
2

Eine Möglichkeit wäre, Ihr Reindex-Skript eine Sperrdatei erstellen zu lassen, damit es prüfen kann, ob bereits eine Instanz des Skripts ausgeführt wird. Sie können auch eine Ausnahmebehandlung hinzufügen, um festzustellen, ob die Suchmaschine aktiv ist.

Eine aufwändigere Alternative wäre die Verwendung einer Art Task Queuer wie Resque und Resque-Scheduler:

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

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

Es gibt auch Qu und Sidekiq:

https://github.com/bkeepers/qu

https://github.com/mperham/sidekiq

Ja, das ist alles Ruby-orientiert, aber Sie können nach "Dingen wie resque" in der Sprache Ihrer Wahl suchen.

cjc
quelle
0

Eine andere Möglichkeit, dies schnell einzurichten, besteht darin, ein Shell-Skript zu starten, wenn der Computer gestartet wird (cron kann dies mit ' @reboot /path/to/my/script.sh' tun , und dann den cron neu starten, um ihn zu starten).

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

Das Skript läuft weiter und Sie haben nur ein Skript gestartet - so viele können gleichzeitig ausgeführt werden - nicht mehr. Einige Smarts dort können auch überprüfen, ob der Indexer ausgeführt wird, und wenn nicht, neu starten oder auf andere Weise versuchen, das Problem zu beheben oder jemanden zu benachrichtigen.

Alister Bulman
quelle
-3

Anstatt dafür cron zu verwenden, würde ich Ihren Job eher als einen Dienst aufbauen, der in einer Schleife ausgeführt wird und als letzter Schritt 60 Sekunden lang ruht, oder möglicherweise häufiger für kleinere Intervalle an verschiedenen Punkten während des Prozesses, um die Last zu verteilen Gleichmäßiger.

Joel Coel
quelle
1
Dies würde weder das Problem beheben noch eine Verbesserung von Cron darstellen.
gparent
Dies würde das Problem beheben, da dann immer nur ein Prozess ausgeführt wird. Es würde cron komplett umgehen.
Joel Coel
Es behebt das Problem nicht, wenn der "Dienst" nicht angezeigt wird, wenn die Suchmaschine ausgeführt wird. Die Logik seines Skripts / Jobs ist das Problem. EDIT: Eigentlich hast du ein bisschen recht, es würde das Problem auf hässliche Weise verbergen.
gparent