Cron-Job für PHP-Skript, das sehr lange Ausführungszeit erfordert

8

Ich habe ein PHP-Skript, das als Cron-Job ausgeführt wird und eine Reihe einfacher Tasks ausführt, die für jeden Benutzer in der Datenbank eine Schleife bilden und etwa 30 Minuten dauern. Dieser Prozess beginnt jede Stunde und muss so schnell und effizient wie möglich sein. Das Problem, das ich habe, ist wie bei jedem Server-Skript, die Ausführungszeit variiert und ich muss die besten Cron-Zeiteinstellungen herausfinden.

Wenn ich Cron jede Minute starte, muss ich die letzte Schleife des Skripts 20 Sekunden vor dem Ende der Minute stoppen, um sicherzustellen, dass die aktuelle Schleife rechtzeitig beendet wird. Im Laufe der Stunde summiert sich dadurch viel Zeit.

Ich frage mich, ob es eine schlechte Idee ist, das php-Ausführungszeitlimit einfach zu entfernen und das Skript einmal pro Stunde auszuführen und es bis zum Ende laufen zu lassen ... ist das eine schlechte Idee?

    
websiteguru 02.11.2010, 22:40
quelle

8 Antworten

5

Angenommen, Sie möchten, dass die Arbeit so schnell wie möglich erledigt wird, verwenden Sie nicht cron. Cron ist gut für Dinge, die zu bestimmten Zeiten passieren müssen. Es wird oft missbraucht, um einen Hintergrundprozess zu simulieren, der im Idealfall Arbeit verarbeitet, sobald die Arbeit erscheint. Sie sollten wahrscheinlich einen Daemon schreiben, der kontinuierlich läuft. (Hinweis: Sie auch bei einer Nachricht / Work-Queue-Typ-System aussehen könnten, gibt es nette Bibliotheken gibt, dies zu tun, auch)

Sie können einen Daemon von Grund auf mit den pcntl Funktionen schreiben (da Sie nicht über mehrere Arbeitsprozesse ist es egal, es ist < a href="http://blog.icerock.com.ar/2010/10/daemon-in-4-lines-of-code/"> super-leicht, einen Prozess im Hintergrund laufen zu bekommen. ) oder betrügen und nur ein Skript, das für immer läuft und über Bildschirm ausführen oder einige solide Bibliothek Code nutzen wie PEAR System: Daemon oder nanoserv

Sobald die daemonization Sachen Pflege genommen wird, alles, was Sie wirklich wichtig eine Schleife aufweist, die für immer läuft. Sie sollten darauf achten, dass das Skript keinen Speicher verliert oder zu viele Ressourcen verbraucht.

Im Allgemeinen können Sie Folgendes tun:

%Vor%

Und es wird ziemlich gut funktionieren.

    
timdev 02.11.2010, 23:05
quelle
2

Anstatt max_execution_time zu setzen, können Sie auch set_time_limit () verwenden, um den Zähler für jede Schleife zurückzusetzen. Dies stellt sicher, dass Ihr Skript nie in der Zeit läuft, es sei denn, es gibt etwas Ernstes innerhalb der aktuellen Schleife (und dauert länger als die max_execution_time).

Im Grunde sollte dies dazu führen, dass Ihr Skript so lange ausgeführt wird, wie es benötigt wird, während es zwischen zwei set_time_limit() -Aufrufen eine Zeitüberschreitung von 30 Sekunden hat.

    
acme 13.09.2012 15:06
quelle
1

Das Zeitlimit auf 0 zu setzen und es so machen zu lassen ist ziemlich typisch für PHP-basierte Cronjobs (nach meiner Erfahrung), aber das ist auch der Punkt, an dem man sich einige wichtige Fragen stellen sollte, wie zum Beispiel "Sollte ich neu schreiben dieser Job in einer kompilierten Sprache? " und "Verwende ich alle meine Tools (Datenbank usw.) mit maximaler Effizienz?"

Das heißt, vielleicht besser, als das Zeitlimit vollständig zu entfernen, wäre es, es auf die Obergrenze zu setzen, die Sie eigentlich wollen. Wenn das 48 Minuten bedeutet, dann set_time_limit(48 * 60);

    
Dereleased 02.11.2010 22:48
quelle
1

Ich denke wirklich, du solltest die Zeit nicht auf 0 setzen, das ist nur auf der Suche nach Ärger. Setzen Sie ihn höchstens auf 59 * 60 Sekunden, aber wenn Sie ihn auf 0 setzen, kann dies zu Sicherheitsproblemen führen. Bleibt ein Skript hängen, bleibt es fast immer hängen, bis der Server-Host die Ausführung stoppt. Es wird als schlechte Praxis angesehen, dies zu tun.

    
LostInTheCode 02.11.2010 22:54
quelle
0

Ich habe die php-Befehlszeilenschnittstelle für ähnliche lange laufende Aufgaben in der Vergangenheit verwendet. Wahrscheinlich möchten Sie das Ausführungszeitlimit für eine Anfrage nicht entfernen.

    
smilingthax 02.11.2010 22:45
quelle
0

Klingt wie eine großartige Idee, wenn es wenig Chance gibt, dass es mehr als eine Stunde dauern wird. Beachten Sie jedoch, dass der falsche Fehler ein wirklich guter Weg sein kann, um länger als erwartet zu dauern.

Um alle möglichen unangenehmen Probleme zu vermeiden, sollten Sie eine Guard-Datei mit der Prozess-ID des Skripts haben. Beim Start sollten Sie überprüfen, ob die Datei nicht existiert oder ob die Prozess-ID in der Datei nicht existiert (durch einen kid (pid, 0) -Aufruf). Wenn diese Bedingungen erfüllt sind, erstellen Sie eine neue Datei mit der PID des Skripts und löschen Sie die Datei, wenn Sie fertig sind.

Dies ist der gleiche Trick, den viele Dämonen verwenden, um sicherzustellen, dass sie nicht bereits läuft. Wenn der Daemon plötzlich beendet wurde, wird die Datei weiterhin existieren, aber die PID des Prozesses wird wahrscheinlich nicht ausgeführt.

    
user335938 02.11.2010 22:47
quelle
0

Je nachdem, was Ihr Skript tut, kann es zu Problemen führen, wenn Sie das Zeitlimit entfernen. Wenn Sie z. B. einen externen Server abfragen, der während der Ausführung des Jobs nicht reagiert, und dass Ihr cron 2 Stunden statt 30 Minuten benötigt, können Sie einen Stack von PHP-Prozessen erhalten, die hochgefahren werden, selbst wenn die vorherigen Ports vorhanden sind Bin noch nicht fertig. Dies kann zu Systeminstabilität und Abstürzen führen.

Sie haben wahrscheinlich zwei Möglichkeiten:

  • Stellen Sie sicher, dass keine andere Instanz Ihres Skripts ausgeführt wird, andernfalls exit () beim Start.
  • Überlegen Sie, Ihren Cronjob in einen Daemon zu ändern.
netcoder 02.11.2010 22:52
quelle
0

Muss es stündlich wie ein Uhrwerk laufen?

Wenn der Job nicht geteilt wurde (Sie haben erwähnt, dass es mehr als eine einfache Aufgabe war), machen Sie jede Aufgabe jede Stunde?

Oder teilen Sie es pro Benutzer, machen A-M auf Stunde, dann N-Z das nächste?

    
Jake 02.11.2010 23:04
quelle

Tags und Links