[php/mysql] Cronjobsteuerung mit php/mysql

BartTheDevil89

Devilution Media
ID: 87739
L
2 Mai 2006
3.960
103
Hallo,

mittlerweile haben ja diverse Scripts, wie das neue wbb3 beispielsweise, eine Steuerung für Cronjobs drin. Also das Script führt die Cronjobs aus und es muss kein Cronjob mehr im Server eingetragen werden.
Aber wie läuft das genau, wie wie setzt man sowas am besten um? Denn das Grundprinzip ist für mich ja verständlich. Also das Script hat ne Datenbank wann das Ding immer durchgeführt werden soll und wann als nächstes. Wenn bei nem Seitenaufruf eben ein Cronjob laut Datenbank wieder durchgeführt werden müsste, dann wird die Datei einfach durchgeführt.
Aber wie wird sowas am serversparendsten umgesetzt? Denn bei wirklich jedem Seitenaufruf diese Datenbank zu überprüfen, ob was durchgeführt werden müsse wäre ja von den Ressourcen extrem aufwendig.

Hab ihr eventuell Vorschläge, bzw. wie würdet ihr so ein Cronjobsystem umsetzen?

Danke;)
 
Würde ich NIEMALS nutzen, in einen Cronjob kommen rechenintensive lange andauernde Aufträge, das kann man doch nicht ausführen, wenn ein User die Seite besucht.

Alternativ eine Lösung, die mir gerade in den Sinn kam, asynchron den Cronjob abarbeiten.
Asynchron? PHP kann das doch gar nicht 8O
Man könnte ja mit fsockopen eine verbindung zum server herstellen und seinen request absenden und gar nicht warten bis das ergebnis berechnet wurde, sondern gleich disconnecten, würde deutlich weniger Zeit kosten.

Wie man das umsetzt? Dafür gibt es caches!
Memcached: nächster Durchlauf als Timestamp abspeichern
 
Würde ich NIEMALS nutzen, in einen Cronjob kommen rechenintensive lange andauernde Aufträge, das kann man doch nicht ausführen, wenn ein User die Seite besucht.

Alternativ eine Lösung, die mir gerade in den Sinn kam, asynchron den Cronjob abarbeiten.
Asynchron? PHP kann das doch gar nicht 8O
Man könnte ja mit fsockopen eine verbindung zum server herstellen und seinen request absenden und gar nicht warten bis das ergebnis berechnet wurde, sondern gleich disconnecten, würde deutlich weniger Zeit kosten.

Wie man das umsetzt? Dafür gibt es caches!
Memcached: nächster Durchlauf als Timestamp abspeichern


Oha...deine Lösungen klingen immer so schön^^......muss mich aber noch bisschen durcharbeiten.

Ziel des ganzen sollte es sein denn Punkt, dass die Cronjobs in den Server eingetragen werden, weglassen zu können.....denn bei einem Script für einen Kunden, bzw. zum Verkauf kommen ne Menge Newbies ran und die haben oft Probleme mit den Cronjobs.
Da ich so ein System aber jetzt schon mehrfach gesehen habe, dachte ich, dass es über einen Trick serversparend umzusetzen sei.
 
Hmh...also ich hab jetzt versucht das ganze mal nachzuvollziehen....aber irgendwie fehlt mich da einfach noch die Erfahrung für. Könntest du vielleicht nochmal näher beschreiben? :roll:
 
PHP:
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 1);
if (!$fp) {
  echo "$errstr ($errno)<br />\n";
} else {
  stream_set_timeout($fp, 100);
  $out  = "GET /cronjob.php HTTP/1.1\r\n";
  $out .= "Host: www.example.com\r\n";
  $out .= "Connection: Close\r\n\r\n";
  fwrite($fp, $out);
  fclose($fp);
}

und beim cronjob dann ignore_user_abort

keine Garantie für Richtigkeit, schnell mal zusammengetippert, sollte denke ich aber den Ansatz klar machen.
 
Würde ich NIEMALS nutzen, in einen Cronjob kommen rechenintensive lange andauernde Aufträge, das kann man doch nicht ausführen, wenn ein User die Seite besucht.

Öhm wieso nicht? Muss halt nur so geschrieben werden dass zuerst die ganzen AUsgaben fütr den User kommen und wenn dann alle Informationen an den User ausgegeben wurden sind kann man ja die Crons loslaufen lassen. Damit bekommt halt der User der die Cronjobs anstößt noch die alten Daten angezeigt aber das dürfte ja relativ egal sein.
 
Öhm wieso nicht? Muss halt nur so geschrieben werden dass zuerst die ganzen AUsgaben fütr den User kommen und wenn dann alle Informationen an den User ausgegeben wurden sind kann man ja die Crons loslaufen lassen. Damit bekommt halt der User der die Cronjobs anstößt noch die alten Daten angezeigt aber das dürfte ja relativ egal sein.
Das kostet aber unnötige Zeit. Wenn dein Cronjob z.B. 25s braucht, biste noch 5s von der Standardmäßig höchsten Ausführungszeit entfernt. Wenn du jetzt aber vorher erst noch die Seite lädst, kann ich das nochmal etwas erhöhen und dann kann es passieren, dass die Zeit doch mal zu knapp wird (eigentlich sollte man sich da sowieso gegen absichern, aber trotzdem mal als Beispiel)
Oder was passiert, wenn der User das laden der Seite abbricht? Dann wird auch der Cronjob abgebrochen und so Sachen wie ignore_user_abort() sind ja nich sonderlich elegant.
 
Es ist nicht standardisiert wie sich Browser in solchen Fällen verhalten müssen.
Der Browser kann genauso gut sagen, dass er erst mit dem Rendering der Website anfängt wenn die Verbindung geschlossen wurde, also defintiv alles übertragen wurde.

Crons sind nunmal dafür gedacht asynchron zu User-Requests zu arbeiten, und das sollte man auch beibehalten, sonst sind es keine Crons mehr :biggrin:
 
PHP:
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 1);
if (!$fp) {
  echo "$errstr ($errno)<br />\n";
} else {
  stream_set_timeout($fp, 100);
  $out  = "GET /cronjob.php HTTP/1.1\r\n";
  $out .= "Host: www.example.com\r\n";
  $out .= "Connection: Close\r\n\r\n";
  fwrite($fp, $out);
  fclose($fp);
}

und beim cronjob dann ignore_user_abort

keine Garantie für Richtigkeit, schnell mal zusammengetippert, sollte denke ich aber den Ansatz klar machen.

Hi,

also tut mir Leid, dass ich da nochmal nachhaken muss, aber sind noch paar Fragen offen.

Hab ich dein System jetzt richtig verstanden?

Du möchtest:

1. Über ne SQL-Datenbank überprüfen, ob ein Cronjob durchgeführt werden muss.
2. Wenn ja, mit dem obrigen Code diesen aufrufen. Allerdings funktioniert der dann so, dass erst die Seite komplett geladen wird und dem Besucher, der eben gerade drauf ist, angezeigt wird und im Hintergrund dann der Cron aufgerufen wird?

Versteh ich das so richtig? Denn auch die nachfolgenden User sind sich ja nicht wirklich einig.
 
1. Über ne SQL-Datenbank überprüfen, ob ein Cronjob durchgeführt werden muss.
ja, kann man so machen

2. Wenn ja, mit dem obrigen Code diesen aufrufen. Allerdings funktioniert der dann so, dass erst die Seite komplett geladen wird und dem Besucher, der eben gerade drauf ist, angezeigt wird und im Hintergrund dann der Cron aufgerufen wird?
nein, das ist was White beschreibt.
Mein "Code" ruft während der Scriptausführung den Cronjob per PHP auf, wartet jedoch nicht, bis dieser fertig ist, sondern beendet gleich wieder die Verbindung, er stößt dne Cronjob also als asynchronen Auftrag an, die komplette Berechnung des Cronjobs wird nicht die Ausführungszeit des Scriptes beeinflussen, was der user gerade aufgerufen hat.

Versteh ich das so richtig? Denn auch die nachfolgenden User sind sich ja nicht wirklich einig.
die "nachfolgenden user" beziehen sich auf die Methodik von white, welche nicht zu empfehlen ist.
 
Ah ja jetzt verstanden.....die Idee is wirklich super. Danke auch für die Erklärung.....

Allerdings eine Frage hab ich noch. Und zwar hast du auch ne Idee wie ich am besten die Zeitsteuerun serversparend umsetzen kann? Also beispielsweise eben, dass ich festlegen kann, dass das Ding jeden Tag um 2 aufgerufen wird. Oder eben alle 20 Minuten...(natürlich sind das ja dann Mindestwerte, denn erst wenn nach 2 Uhr beispielsweise ein Seitenaufruf erfolgt, wird der ja aufgerufen)
Aber das müsste ja so serversparend wie möglich durchgeführt werden dann.....am besten nen Timestamp für ersellen und nach dem Ausführen wieder einen neuen setzen?
 
Crons sind nunmal dafür gedacht asynchron zu User-Requests zu arbeiten, und das sollte man auch beibehalten, sonst sind es keine Crons mehr :biggrin:

Öhm, nö. Crons sind dazu da, Zeit gesteuerte wiederkehrende Aufgabe zu erledigen.

Dein beschriebenes Script ist davon aber weit entfernt, da der Auslöser für die Datenbank-Abfrage (um die Jobs zu holen) nicht mehr über Zeit, sondern durch einen Surfer bestimmt wird.
 
Öhm, nö. Crons sind dazu da, Zeit gesteuerte wiederkehrende Aufgabe zu erledigen.
ja weiß ich.
aber es war eben gemeint, dass ein "Cron" nicht in einem User-Request laufen soll.

Dein beschriebenes Script ist davon aber weit entfernt, da der Auslöser für die Datenbank-Abfrage (um die Jobs zu holen) nicht mehr über Zeit, sondern durch einen Surfer bestimmt wird.
Ist mir ebenfalls bewusst, aber genau sowas war eben gefragt.
 
Zuletzt bearbeitet:
Ja ich hab halt gemerkt, dass die Erstellung von Cronjobs für viele Anfänger ein Problem ist...und deswegen, nachdem ich solche Varianten bereits in anderen Systemen gefunden habe, dachte ich, dass es so genauso möglich wäre es zu lösen. Und wenn ich jetzt noch ne serversparende Variante für die Zeitüberprüfung finde und die Crons so sind, dass sie eben auch verspätet durchlaufen können, sollte das ja alles kein Problem sein.