heinetz: Cronjobs mit pho einrichten

Hallo Forum,

in meinem selbstgezimmerten PHP-CMS gibt es diverse Aktionen, die mein Redakteur ausführen kann. Diese Aktionen sollen nun automatisch zu bestimmten Zeitpunkten ausgeführt werden. Auf dem Server laufen bereits einige Cronjobs, die mir der Serveradmin eingerichtet hat. Nun brauche ich für diese  Aktionen aber ein Userinterface, mit dem mein Redakteur die zeitlich gesteuerten Aktionen selbst beeinflussen kann … oder kurz ich möchte per PHP Cronjobs anlegen, editieren und löschen und muss dazu wissen, wie das mit den Cronjobs überhaupt läuft.

Wenn ich das richtig verstanden habe, macht cronjob nichts anderes, als die Anweisungen in einer Datei crontab auszuführen und man müsste also grundsätzlich nur mit PHP diese Datei ändern. Mir sind ein paar Dinge nicht ganz klar:

1. Meine Aktionen sollen sich nicht wiederholen, was bei Cronjobs ja für gewöhnlich der Fall ist. Ist ein Cronjob trotzdem der richtige Weg?

2. Und dann war da noch das Usermanagement … Wenn Ich das richtig verstanden habe gibt es einen Zusammenhang zwischen Usern und Cronjobs. Ich habe mal versucht, mir mit einem PHP-Skript:

$output = shell_exec('crontab -l');  
echo $output;

… die Cronjobs auf dem Server anzeigen zu lassen, sehe aber nichts. Das interpretiere ich so, dass
der User PHP hier nur "seine" Cronjobs angezeigt bekommt und da gibt's einfach keine, den die auf dem Server bereits eingerichteten Cronjobs "gehören" nicht PHP.

3. Das Ändern der crontab geschieht nicht einfach, indem PHP eine Datei crontab.txt irgendwo hinschreibt sondern mit dem Befehl "crontab".

danke vorab und

beste gruesse,
heientz

  1. Hello,

    der User PHP hier nur "seine" Cronjobs angezeigt bekommt und da gibt's einfach keine, den die auf dem Server bereits eingerichteten Cronjobs "gehören" nicht PHP.

    Grundsätzlich würde ich ein Subsystem daraus machen.
    In die originale Crontab kommt nur ein Shell-Aufruf für ein PHP-Modul, das Du erstellen musst.

    Dieses hat dann Zugriff auf die Datenbank
    Dieses kann die "PHP-Jobs" veranlassen

    Voraussetzung ist aber, dass das Modul exec() ausführen darf und die eigenen Jobs abspalten und in den Hintergrund stellen darf. Sonst könnte es Probleme geben.

    Das Pflegen der Tabelle ist dann ja nicht mehr so schwer.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bikers-lodge.com
    1. Grundsätzlich würde ich ein Subsystem daraus machen.
      In die originale Crontab kommt nur ein Shell-Aufruf für ein PHP-Modul, das Du erstellen musst.

      Du meinst, ich bzw. mein Redakteur speichert die "Jobs" irgendwo (DB-Tabelle "jobs") ab. Der Cronjob selbst besteht nur im regelmässigen Aufruf eines PHP-Skripts ("dojobs.php"), dass auf die Tabelle "jobs" zugreift und die [i]überfälligen[/i] "Jobs" ausführt.

      [i]überfällig[/i]:

      Das PHP-Script "dojobs.php" wird regelmässig (bsp. alle 15 Minuten) von cron aufgerufen. Bsp. am 23.05.14 11:00 Uhr und dann wieder um 11:15 Uhr. Das PHP-Skript "dojobs.php" findet in der Tabelle "jobs" einen "Job", der um 11:10 Uhr ausgeführt werden soll. Um 11:00 Uhr ist es folglich noch zu früh, um 11:15 Uhr wird der "überfällige" Job dann ausgeführt.

      "Überfällig" ist natürlich überspitzt … formuliert und nur für mein Verständnis. Das würde man natürlich abfangen können, indem man dem Redakteur nur die Möglichkeit gibt, einen Job entweder für 11:00 Uhr oder für 11:15 Uhr anzulegen.

      beste gruesse,
      heinetz

      1. Hello,

        Grundsätzlich würde ich ein Subsystem daraus machen.
        In die originale Crontab kommt nur ein Shell-Aufruf für ein PHP-Modul, das Du erstellen musst.

        Du meinst, ich bzw. mein Redakteur speichert die "Jobs" irgendwo (DB-Tabelle "jobs") ab. Der Cronjob selbst besteht nur im regelmässigen Aufruf eines PHP-Skripts ("dojobs.php"), dass auf die Tabelle "jobs" zugreift und die [i]überfälligen[/i] "Jobs" ausführt.

        [i]überfällig[/i]:

        Das PHP-Script "dojobs.php" wird regelmässig (bsp. alle 15 Minuten) von cron aufgerufen. Bsp. am 23.05.14 11:00 Uhr und dann wieder um 11:15 Uhr. Das PHP-Skript "dojobs.php" findet in der Tabelle "jobs" einen "Job", der um 11:10 Uhr ausgeführt werden soll. Um 11:00 Uhr ist es folglich noch zu früh, um 11:15 Uhr wird der "überfällige" Job dann ausgeführt.

        "Überfällig" ist natürlich überspitzt … formuliert und nur für mein Verständnis. Das würde man natürlich abfangen können, indem man dem Redakteur nur die Möglichkeit gibt, einen Job entweder für 11:00 Uhr oder für 11:15 Uhr anzulegen.

        Ja, das ginge.
        Man könnte aber auch das PHP-Script dazu bringen, dass es z. B. 15 Minuten läuft und aller 30 Sekunden in die Datenbank schaut.

        Dazu musst Du das Recht haben, Forks zu produzieren.

        http://forum.de.selfhtml.org/archiv/2010/6/t198495/#m1333275
        http://forum.de.selfhtml.org/archiv/2009/12/t193945/#m1296047
        http://forum.de.selfhtml.org/archiv/2009/12/t193945/#m1296056

        Also:

        Cron startet den PHP-interpreter und übergibt ihm das Script. Er stellt auch den Job in den Hintergrund. Das Script läuft dann z.B. 20 Minuten in einer Schleife. Danach bendet es sich selbst.
        Es findet Jobs in der Datenbank und lässt die ebenfalls im Hintergrund ausführen. Dadurch kann das Script selber weiterlaufen.

        Du musst nun nur auf saubere Maßnahmen für den konkurrierenden Betrieb achten. Sonst kracht es.

        Cron              -               -               -               -
        Kontrollscript    --------------------
                                          --------------------
                                                          --------------------
                                                                          --------------------
        Jobs              --
                           ----     ---      ------
                                          -   --     -   ---
                                                           ----   --     ---------------
                                                                            --   --    ----

        Ich hoffe, Du kannst Dir unter meiner "Grafik" 'was vorstellen und siehst, wie ich das mit dem konkurrierenden Betrieb meine.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bikers-lodge.com
        1. Moin,

          Man könnte aber auch das PHP-Script dazu bringen, dass es z. B. 15 Minuten läuft und aller 30 Sekunden in die Datenbank schaut.

          Oder man startet das PHP-Skript einfach in Hintergrund als "Dienst", der alle 30 Sekunden in die Datenbank schaut und sich _nicht_ beendet. Wozu das Programm beenden und dann wieder starten?

          Statts PHP könnte man auch Node.js oder Python nehmen.

          Grüße Marco

          --
          Ich spreche Spaghetticode - fließend.
          1. Hello,

            Man könnte aber auch das PHP-Script dazu bringen, dass es z. B. 15 Minuten läuft und aller 30 Sekunden in die Datenbank schaut.

            Oder man startet das PHP-Skript einfach in Hintergrund als "Dienst", der alle 30 Sekunden in die Datenbank schaut und sich _nicht_ beendet. Wozu das Programm beenden und dann wieder starten?

            Das ist theoretisch möglich.
            Dazu müsste der Interpreter nebst Script dann aber in die Startkonfiguration des Servers aufgenommen werden. Anderenfalls wäre ja nicht sichergestellt, dass es auch läuft.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bikers-lodge.com
        2. hi,

          "Überfällig" ist natürlich überspitzt … formuliert und nur für mein Verständnis. Das würde man natürlich abfangen können, indem man dem Redakteur nur die Möglichkeit gibt, einen Job entweder für 11:00 Uhr oder für 11:15 Uhr anzulegen.

          Ja, das ginge.

          Danke, das reicht mir als überschaubare Lösung. Aber danke auch für die mühsame Skizzierung der Alternativlösung. Gute Inspiration!

          beste gruesse,
          heinetz

  2. Moin,

    1. Meine Aktionen sollen sich nicht wiederholen, was bei Cronjobs ja für gewöhnlich der Fall ist. Ist ein Cronjob trotzdem der richtige Weg?

    du könntest einen Cronjob anlegen, der beispielsweise alle 10 Minuten läuft und nachsieht, ob etwas getan werden muss. Die Aufgaben, die dann zeitgesteuert ausgeführt werden sollen, könntest du in einer Datenbank speichern und den Eintrag nach der Ausführung löschen/auf "erledigt" setzen.

    1. Und dann war da noch das Usermanagement … Wenn Ich das richtig verstanden habe gibt es einen Zusammenhang zwischen Usern und Cronjobs. Ich habe mal versucht, mir mit einem PHP-Skript:

    Normalerweise werden Cronjobs mit Root-Rechten ausgeführt, sofern nicht anders angegeben.

    Das interpretiere ich so, dass der User PHP hier nur "seine" Cronjobs angezeigt bekommt und da gibt's einfach keine, den die auf dem Server bereits eingerichteten Cronjobs "gehören" nicht PHP.

    Das ist eigentlich nicht der Fall. Es kann Cron-Jobs geben, die nicht in der Crontab stehen. Für Cronjobs gibt es bei Ubuntu beispielsweise das Verzeichnis /etc/cron.d in dem die entsprechenden Skripte dann abgelegt werden können. Außerdem gibt es noch "anacron", ein Paket welches die Ordner
    /etc/cron.daily
    /etc/cron.hourly
    /etc/cron.monthly
    /etc/cron.weekly
    jeweils zu den Zeiten abarbeitet (täglich, wöchentlich, ...)

    1. Das Ändern der crontab geschieht nicht einfach, indem PHP eine Datei crontab.txt irgendwo hinschreibt sondern mit dem Befehl "crontab".

    Da deine Aufgaben nicht wiederholt werden sollen wäre für mich – wie gesagt – folgender Aufbau am sinnvollsten:

    1. Redakteur legt Job an => PHP-Skript schreibt die erforderlichen Infos in eine Datenbank
    2. Cron startet alle 10 Minuten (oder eben die granularste Einheit, die du brauchst) ein weiteres PHP-Skript (oder Perl, Bash, ...) welches prüft ob in der Datenbank ein Job steht, der ausgeführt werden soll und führt ihn aus. Danach wird der Datensatz entweder gelöscht oder mit einem Flag versehen, welches verhindert, dass er erneut ausgeführt wird (beispielsweise weil du nachvollziehen willst, welche Aufgaben abgearbeitet wurden).

    Grüße Marco

    --
    Ich spreche Spaghetticode - fließend.