2010-08-25 2 views
6

Ich habe ein PHP-Skript, das einmal alle 5 Minuten ausgeführt werden muss. Momentan verwende ich einen Cron-Job, um es auszuführen (und es funktioniert großartig), aber mein Host erlaubt nur eine Mindestzeit von 15 Minuten.Ausführen eines PHP-Skripts alle 5 Minuten und Vermeiden von Race-Bedingungen

Also meine Frage ist, kann ich Besucher verwenden, um die Ausführung eines PHP-Skript alle 5 Minuten auszulösen. Ich kann einfach das letzte Mal aufzeichnen und es basierend auf der verstrichenen Zeit erneut ausführen.

Allerdings mache ich mir Sorgen über die Rennen Bedingungen. Es ist wichtig, dass das Skript nur einmal alle 5 Minuten ausgeführt wird.

Mein Skript dauert etwa 60 Sekunden. Es schreibt während dieser Zeit in ein paar Dateien. Wenn das Skript mehr als einmal ausgeführt wird, werden Dateien beschädigt. Auch, wenn ich 10 Minuten lang keinen Besucher bekomme, ist es in Ordnung, wenn ich einmal lief, wenn der nächste Besucher kommt.

Gibt es einen Standardweg, um diese Aufgabe zu erfüllen?

Danke!

+0

Ich bin mir nicht sicher, ob ich das Problem verstehe. Kann Ihr Host nicht zulassen, dass Cron-Jobs öfter als alle 15 Minuten ausgeführt werden? – Icode4food

+1

Der Standardweg wäre die Verwendung eines Webhosts, der keine schlechten, willkürlichen Regeln auf Cron vorschreibt. Wer zum Teufel macht das? – Erik

+1

Wechseln Sie Hosts. Problem gelöst – Stoosh

Antwort

6

Haben Sie darüber nachgedacht, Ihr Skript nur eine Endlosschleife mit einer sleep auszuführen, um zwischen den Iterationen 5 Minuten zu warten?

for (;;) 
{ 
    perform_actions(); 
    sleep(300); 
} 

Alternativ können Sie eine Datei haben (zum Beispiel is_running) und eine exklusive lock auf sie zu Beginn des Skripts erhalten, die am Ende freigegeben wird. Zumindest werden Sie auf diese Weise nichts Zerstörendes tun.

Sie können diese beiden Lösungen auch kombinieren.

$fp = fopen("is_running", "r+"); 

/* is it already running? */ 
if (! flock($fp, LOCK_EX | LOCK_NB)) return; 

for (;;) 
{ 
    perform_actions(); 
    sleep(300); 
} 

Und dann muss der Cron-Job immer noch alle 15 Minuten ausgeführt werden. Wenn der Prozess noch läuft, wird er einfach ausbuchen, sonst wird er alle 5 Minuten neu gestartet und aktualisiert.

+0

Das scheint eine gute Idee und eine ziemlich gute Arbeit zu sein. Ich schätze, ich muss php's set_time_limit aufrufen. Und dann hoffe ich, dass mein Gastgeber nicht lange laufende Prozesse automatisch beenden wird ... Trotzdem scheint dies meine beste Wette zu sein. Vielen Dank. – Imbue

+1

'set_time_limit' ist die Funktion, die Sie zum Anpassen des Timeouts benötigen. http://php.net/manual/en/function.set-time-limit.php Ich würde es jedes Mal auf 330 setzen, wenn das Skript ausgeführt wird, damit Sie sich keine Sorgen machen müssen. – Icode4food

+1

Nur um Sie wissen zu lassen, erlaubte der Host meinem Skript, für ca. laufen. 26 Stunden vor dem Töten. Kurz danach erschien Cron auf einem anderen, der bemerkte, dass die Datei entsperrt war und ich wieder im Geschäft war. Eine Sache, die mich erschreckt, ist, was passieren würde, wenn der Host mein Skript beim Schreiben von Daten tötet. In diesem Fall könnten Daten beschädigt werden, bis Cron ein anderes Skript ausführen kann. Mit anderen Worten würde ich ein paar Mal im Jahr wahrscheinlich beschädigte Daten für ungefähr 5-10 Minuten bedienen. – Imbue

1

Wenn Sie nicht das tun können, was @Brandon vorgeschlagen hat, würde ich die Annäherung an die gleiche Weise wie beim Schreiben eines Daemons in PHP empfehlen (nicht die beste Lösung, aber ich wurde praktisch dazu gezwungen).

Auch in meinem Fall hat das Skript auf eine (Protokoll-) Datei zugegriffen und die Verarbeitung durchgeführt, danach wurden die Ergebnisse in die Datenbank eingefügt. Um sicherzustellen, dass nicht zwei Dateien gleichzeitig ausgeführt werden, habe ich eine "Status" -Datei erstellt, in der das Skript eine Sperre erlangte und wenn dies nicht möglich war, wenn dies fehlgeschlagen war.

$fh = fopen('status_file', 'w'); 

/** 
* LOCK_NB is required because otherwise your script would stall until 
* a lock is aquired, queing a bunch of scripts. 
*/ 
if(!flock($fh, LOCK_EX | LOCK_NB)) { 
    exit 1; // our job is done here 
} 
4

Lahme Antwort für eine lahme Situation (der ISP, nicht das Plakat). Planen Sie 12 Cron-Jobs, die alle das gleiche Skript aufrufen und jeweils einmal pro Stunde ausgeführt werden, aber eine andere 5-Minuten-Marke aufrufen.

00 * * * * root echo "run at :00 of every hour" 
05 * * * * root echo "run at :05 of every hour" 
10 * * * * root echo "run at :10 of every hour" 

usw. bis: 55. Aber ich stehe zu meinem ursprünglichen Kommentar - einen neuen ISP zu finden :)

+1

Ich bin sicher, das würde funktionieren, und es ist wahrscheinlich eine anständige Lösung, aber ich habe Angst, was passieren würde, wenn mein Gastgeber es bemerkt. – Imbue

+3

@Imbue - Also meinst du, dein Gastgeber würde auf eine Endlosschleife freundlicher reagieren? –

+0

Ich denke, eine Endlosschleife, die fast ihre ganze Zeit im Schlaf verbringt, wäre weniger auffällig und vielleicht ein bisschen weniger trotzig. Oder nicht. Es ist schwer wirklich zu sagen. – Imbue

0

Sie können The Fat Controller verwenden, um ein Skript in 5-Minuten-Intervallen auszuführen. Im Gegensatz zu CRON garantiert es das Intervall zwischen dem Ende einer Instanz des Skripts und dem Beginn eines anderen.

+0

Hallo, ich habe einen Kommentar auf Ihrer Website mit Fragen über TheFatController mein Name ist "Geocine" –

0

Die Antwort darauf, ob Besucher dieses Skript starten können, ist ja. Sie können das Skript ausführen, wenn Besucher eine Seite eingeben. Sie möchten die Startzeit speichern, aber auch ein Attribut für die Ausführung. Dies sollte jegliche Konfliktmöglichkeit vermeiden, wenn Sie versuchen, Ihre Daten zu aktualisieren.Ich habe auch ein zusätzliches Feld für die Mail-Warnung eingefügt, das Sie verwenden können, wenn die Laufzeit das übertrifft, was Sie als außerhalb der maximalen Zeit erwarten würden. Sie können sich dann vom Skript eine Warn-E-Mail senden lassen, dass Ihr Skript über die maximale Zeit hinaus ausgeführt wurde. Ich habe diese Status persönlich in Datenbanken gespeichert, sie können aber auch in Dateien gespeichert werden.

Verwandte Themen