|

So stellst Du WordPress auf einen echten Cronjob um

WordPress auf echten Cronjob umstellen

Unter einem Cronjob versteht man eine wiederkehrende Aufgabe, die automatisiert ausgeführt wird. Für bestimmte Aufgaben hat WordPress ein Pseudo-Cron-System integriert. Einen echten Cronjob zur Automatisierung von WordPress zu verwenden hat durchaus Vorteile.

Viele Betriebssysteme bieten ein sogenanntes Cron-System, mit dem sich zu definierten Zeiten automatisiert Aufgaben ausführen lassen. Die auszuführenden Aufgaben werden in einer Tabelle gespeichert, der sogenannten Crontab. Die einzelnen Aufgaben, die ausgeführt werden, nennt man Cronjobs. Damit diese Cronjobs zu den festgelegten Zeiten auch gestartet werden, muss das Cron-System logischerweise permanent im Hintergrund laufen.

WordPress läuft nicht ununterbrochen am Webserver, sondern wird immer dann gestartet, wenn eine Seite aufgerufen wird. Damit ist klar, dass WordPress kein echtes Cron-System besitzen kann. Um bestimmte Aufgaben regelmäßig zu automatisieren, bringt WordPress ein Pseudo-Cron-System mit. Ähnlich wie in einer Crontab können auch in WordPress automatisch auszuführende Aufgaben in einer Tabelle gespeichert werden.

Das WordPress Pseudo-Cron-System

Im Unterschied zu einem echten Cron-System arbeitet der WordPress-Cron nicht mit Zeitpunkten sondern mit Intervallen. Diese Intervalle werden in Sekunden definiert. Ein Intervall von 86.400 Sekunden bedeutet, dass alle Jobs, denen dieses Intervall zugewiesen ist, einmal pro Tag laufen sollen. Die Festlegung einer genauen Uhrzeit, wann das passieren soll, ist nicht möglich.

Damit sind wir beim Nachteil des Pseudo-Cron-Systems von WordPress. Es würde schlicht und einfach keinen Sinn machen, einen Job beispielsweise täglich exakt um 10:15 Uhr ausführen lassen zu wollen. Wenn um die gewünschte Uhrzeit gerade niemand eine Seite aufruft, dann läuft WordPress zu dieser Zeit nicht. Der Job würde nicht ausgeführt.

Aus dem Grund wird über die Systematik der Intervalle festgelegt, wann welcher Job frühestens das nächste Mal laufen soll. Aufgrund des Intervalls berechnet WordPress Datum und Uhrzeit, wann ein Job theoretisch das nächste Mal ausgeführt werden sollte. Bei jedem Aufruf von WordPress – also bei jedem Aufruf irgendeiner Seite – überprüft WordPress diese Tabelle darauf, ob es Jobs gibt, die zum jetzigen Zeitpunkt ausgeführt werden müssen oder die bereits früher einmal dran gewesen wären.

Je nach Besucherfrequenz auf Deiner Website verschieben sich die tatsächlichen Startzeitpunkte der Jobs also teilweise recht stark. Zu welchen Zeiten welche Jobs gestartet werden, ist nicht in erster Linie von der Uhrzeit abhängig. Der wichtigste Faktor für die Ausführung der WordPress-Cronjobs ist die Häufigkeit der Besuche Deiner Website. Abhängig von Intervall und Besucherfrequenz läuft ein Job dadurch vielleicht überhaupt wesentlich weniger häufig als das eigentlich der Fall sein sollte.

Im Prinzip ist das ein geniales System. So wird eine Crontab simuliert, ohne dass ein echtes Cron-System zur Verfügung steht. Ein echtes Cron-System müsste wie bereits erwähnt permanent laufen. So ein System ist nur mit WordPress alleine schlicht und einfach unmöglich. Das Pseudo-Cron-System von WordPress ist eine tolle Lösung des Problems.

In vielen Fällen ist dieses System auch absolut ausreichend. Häufig spielt es schlicht und einfach keine Rolle, wann genau die Jobs laufen. Beispielsweise verwendet WordPress solche Cronjobs um im Intervall von 12 Stunden zu überprüfen, ob Updates zur Verfügung stehen. Selbst wenn diese Prüfungen erst einige Stunden später laufen, ist das für die meisten Anwender von WordPress absolut kein Problem.

Die Vorteile echter Cronjobs

Dennoch kann es sinnvoll sein, einen echten Cronjob zu verwenden. Das ist sogar relativ einfach machbar. Der Trick dabei ist, dass man einen echten Cronjob einrichtet, der dann einfach den WordPress Cron ausführt. An der Arbeitsweise des Pseudo-Cron-System von WordPress ändert sich dadurch nichts. Dieses arbeitet weiterhin mit Intervallen und nicht mit Startzeitpunkten. Der echte Cronjob stellt aber sicher, dass der WordPress Cron in regelmäßigen Abständen gestartet wird und nicht nur dann, wenn ein Besucher eine Seite aufruft. Somit wird auch nur ein einziger Cronjob benötigt.

Ein weiterer großer Vorteil liegt darin, dass sich der WordPress Cron dann deaktivieren lässt. WordPress muss so nicht mehr bei jedem einzelnen Aufruf überprüfen ob Cronjobs anstehen, die ausgeführt werden müssen. Das spart unnötige Last am Server. Schlauerweise werden Cronjobs erst ausgeführt, nachdem die angefragte Seite an den Benutzer ausgeliefert worden ist. Das Ausführen der Cronjobs wirkt sich also eigentlich nicht auf die #ladezeit der einzelnen Seite aus. Finden aber viele Zugriffe zur gleichen Zeit statt wirkt sich die durch die Cronjobs verursachte Last in Summe aber doch auf die #performance der Website aus.

Den WordPress Cron deaktivieren

Es ist also sinnvoll, den WordPress Cron bei Verwendung eines echten Cronjobs zu deaktivieren. Das bringt noch einen weiteren Vorteil mit sich. Stehen viele Aufgaben an, die durch den Cronjob ausgeführt werden müssen, dann benötigt deren Ausführung möglicherweise eine gewisse Zeit. Wird der Cron im Zuge des Aufrufs einer Seite ausgeführt, so summiert sich die gesamte Laufzeit vom Aufruf der Seite über deren Auslieferung bis zum Ende aller durch den Cron auszuführenden Aufgaben. Das kann möglicherweise mit der maximal erlaubten Script-Laufzeit ein Problem werden. Wird der WordPress Cron deaktiviert und die Ausführung von einem echten Cronjob angestoßen, dann steht die maximale Script-Laufzeit ausschließlich für die automatisch auszuführenden Aufgaben zur Verfügung.

Der WordPress Cron lässt sich ganz einfach mit einem Eintrag in der Datei wp-config.php deaktivieren. Du findest diese Datei im Hauptverzeichnis Deiner WordPress-Installation.

Den WordPress Cron per Cronjob aufrufen

Damit wird der WordPress Cron nun nicht mehr bei jedem Aufruf gestartet. Der Aufruf erfolgt dann durch den echten Cronjob. Um den WordPress Cron aufzurufen muss die Datei wp-cron.php aufgerufen werden, die sich ebenfalls im WordPress-Hauptverzeichnis befindet.

Du kannst die Verarbeitung einfach mit Deinem Browser starten indem Du die Adresse https://www.example.com/wordpress/wp-cron.php aufrufst, wobei Du natürlich www.example.com durch Deine Domain ersetzt und wordpress durch das Verzeichnis, in dem Du WordPress installiert hast. Da der Cron für die Ausführung im Hintergrund gedacht ist erzeugt er auch keine Ausgabe. Das Ergebnis dieses Aufrufs ist also eine leere Seite. Das ist in Ordnung so.

Wer direkten Zugang zur Linux Konsole des Webservers hat, richtet den Cronjob dort direkt über die Crontab ein. Das trifft wahrscheinlich auf die wenigsten Nutzer von WordPress zu und wer einen Server mit vollem Root-Zugang nutzt, der hat wahrscheinlich ohnehin das entsprechende Know-how. Deshalb verzichte ich auf eine Beschreibung der Einrichtung unter Linux.

Die meisten Webhoster bieten die Möglichkeit an, Cronjobs relativ einfach über die jeweilige Online-Verwaltung einzurichten. Da das bei jedem Anbieter anders aussieht, macht es wenig Sinn, den Ablauf hier näher zu beschreiben. Da einige Hoster das Tool Plesk für die Verwaltung einsetzen möchte ich mit dem folgenden Screenshot einfach nur exemplarisch zeigen, wie die Anlage eines Cronjobs bei Plesk aussieht.

So stellst Du WordPress auf einen echten Cronjob um - Cronjob mit Plesk einrichten

Genauso wie bei Plesk ist es wahrscheinlich auch bei den individuellen Tools der diversen Hoster in den meisten Fällen möglich, direkt einen HTTP-Aufruf als Cronjob einzurichten. Bei Plesk muss man in dem Fall einfach „URL abrufen“ auswählen, bei meinem Hoster heißt der entsprechende Punkt zum Beispiel „HTTP Aufruf per URL“. Wenn diese Möglichkeit vorhanden ist, dann muss nur die oben bereits genannte Adresse eingetragen werden.

Bietet Dein Hoster die Möglichkeit eines HTTP-Aufrufs bei den Cronjobs nicht an, dann verwendest Du einfach das Linux-Kommando wget, um die URL per HTTP aufzurufen. Der komplette Aufruf lautet dann also etwa wget https://www.example.com/wordpress/wp-cron.php.

Bei den meisten Tools ist es recht einfach, das Intervall, in dem der Aufruf erfolgen soll, festzulegen. Bei Plesk ist das etwas umständlicher, da hier mit der Crontab-Syntax gearbeitet werden muss. Da das aber wie bereits erwähnt in jedem Tool anders aussieht, kann ich hier nicht näher darauf eingehen.

Bei einem sehr günstigen Hostingpaket hast Du eventuell nicht die Möglichkeit, Cronjobs einzurichten. Wirf dazu einen Blick in die Leistungsbeschreibung Deines Hosters.  Vielleicht ist es möglich, mit geringen zusätzlichen monatlichen Kosten Cronjobs als Option dazuzubuchen. Oder es macht für Dich vielleicht ohnehin Sinn, auf ein höherwertigeres Paket umzusteigen, in dem auch Cronjobs möglich sind.

Alternativ dazu gibt es auch die Möglichkeit, die URL regelmäßig von einem externen Cronjobservice aus aufzurufen. Dabei handelt es sich um spezialisierte Dienste, die nichts anderes machen als zeitgesteuert eine bestimmte Web-Adresse aufzurufen – also genau das, was man für WordPress benötigt.

Ein bekannter Dienst ist beispielsweise Cronjob.de. Im kostenlosen Tarif ist genau ein Cronjob möglich, das kleinstmögliche Intervall liegt bei fünf Minuten. Nutzer des kostenlosen Tarifs müssen sich allerdings mindestens einmal alle acht Wochen anmelden, damit der eingerichtete Job aktiv bleibt. Für kleines Geld gibt es zusätzliche Leistungen. Der Dienst cron-job.org ist sogar komplett kostenlos, erlaubt unbegrenzt viele Cronjobs und das kleinstmögliche Intervall liegt bei einer Minute. Mit keinem der beiden genannten Dienste habe ich bisher persönlich Erfahrungen gemacht, da ich Cronjobs bisher immer direkt bei meinem Hoster eingerichtet habe.

Fazit

Wer mit dem Pseudo-Cron von WordPress weder in Bezug auf die Häufigkeit der Ausführungen noch in Bezug auf die Server-Last ein Problem hat, kann im Prinzip auf einen echten Cronjob verzichten. Ein echter Cronjobs ist jedoch einfach eingerichtet und daher spricht nichts dagegen, in jedem Fall einen echten Cronjob zu verwenden. Wer eine regelmäßige Ausführung sicherstellen oder unnötige Server-Last reduzieren möchte, benötigt einen echten Cronjob.

Ein konkretes Beispiel könnte der Versand von Mails sein. Wer kein externes Newsletter-System einsetzt, sondern die Verwaltung des Verteilers und den Versand am eigenen Server mit einem entsprechenden #plugin erledigt, sollte beispielsweise einen echten Cronjob verwenden um einen zeitgerechten Versand sicherzustellen. Häufig senden solche Systeme nicht alle Mails auf einmal sondern in Paketen. Damit eine Abarbeitung der gesamten Verteilerliste in einer vernünftigen Zeit sichergestellt werden kann ist der Einsatz eines echten Cronjobs unbedingt empfehlenswert.

Ähnliche Szenarien gibt es einige. Einen echten Cronjob für die automatisierten Aufgaben von WordPress zu nutzen ist keine Hexerei und nur eine Sache von ein paar Minuten.

Ähnliche Beiträge

22 Kommentare

    1. Hallo Ole,

      das lässt sich pauschal nicht sagen. Es kommt darauf, welche Jobs bei Dir im Cron laufen. Wenn es nur die normalen Jobs sind, die von WordPress standardmäßig erstellt werden, dann reicht einmal täglich aus. Wenn Du irgendwelche Plugins installiert hast, die Jobs in den Cron eintragen, die öfters laufen sollen, dann natürlich dementsprechend öfters. Wenn dem so wäre, dann wüsstest Du das aber bestimmt und deshalb gehe ich davon aus, dass einmal pro Tag ausreicht. Wenn es Dich interessiert, welche Cronjobs aktiv sind, dann kann ich Dir das Plugin WP Crontrol empfehlen. Damit kannst Du Dir die Jobs im WordPress Admin anzeigen lassen.

      Liebe Grüße
      Peter

    2. Wer mit Datumsangaben in der Zukunft die automatische, zeitgesteuerte Veröffentlichung von Beiträgen in seinem Blog plant, sollte einen kürzeren Intervall wählen. Wenn es dir reicht, dass geplante Artikel nur einmal am Tag geprüft werden, genügen natürlich 24 Stunden. Sollte die Veröffentlichung „genauer“ erfolgen, müsste die Auflösung des Cronjobs entsprechend feiner gewählt werden. Ob das nun jede Stunde, jede halbe Stunde oder alle 15 Minuten bedeutet, ist dir überlassen.

      Man sollte sich bewusst sein, dass jede Ausführung des Cronjobs auch ein Aufruf der Website ist. Das jede Minute machen zu lassen, ist also auch nicht unbedingt klug. Ich denke, alle Angaben zwischen 24 Stunden und 15 Minuten sind in Ordnung.

      1. Vielen Dank für Deinen Hinweis. Da ich nicht mit geplanten Beiträgen arbeite, habe ich daran nicht gedacht.

        Das Veröffentlichen geplanter Beiträge ist ein Sonderfall im WordPress Cron System. Hierfür gibt es keinen Cronjob, der regelmäßig läuft. Wird ein geplanter Beitrag erstellt, wird ein Cronjob erzeugt, der nur einmal zum Veröffentlichungszeitpunkt läuft und diesen einen Beitrag veröffentlicht. Aus diesem Grund ist das Verwenden geplanter Beiträge bei Websites mit geringem Besuchsvolumen auch gefährlich. Da kann es leicht vorkommen, dass der Veröffentlichungszeitpunkt verpasst und ein geplanter Beitrag nicht veröffentlicht wird. Da der Cronjob nicht regelmäßig läuft, wird die Veröffentlichung auch nicht bei nächster Gelegenheit nachgeholt.

    1. Vielen Dank für den Hinweis.

      Wird der Aufruf wie in Deinem Fall über die Corntab gesteuert, dann wird standardmäßig die Ausgabe in eine Datei umgeleitet. Mit der Option „-O /dev/null“ wird die Ausgabe nach /dev/null umgeleitet, sodass keine Datei gespeichert wird. Allgemein wird empfohlen, zusätzlich auch noch die Option „-q“ (quiet) zu verwenden. Warum man beides kombinieren soll, weiß ich aber ehrlich gesagt nicht.
      Nebenbei bemerkt bedeutet „*/15“ alle 15 Minuten und nicht jede Minute…

      LG
      Peter

    2. Vorerst vielen an den Tutorial Blog Verfasser

      Hallo Nick,
      ich glaube der Verfasser diese Blog Tutorial Seite hat mehr als genug als Wissen zu Grunde gelegt und veröffentlicht. Keine Anleitung im Internet ist als „eins zu eins“ übernehmen, sondern lediglich als Leitfaden zu sehen.

      der kürzeste Weg mit wget ohne den Response auszugeben und ohne den /dev/null in Anspruch zu nehmen, wäre

      wget -qO- „https://mydomain.ch/wp-cron.php“

      und wenn du mit wget dich beschäftigst wirst du merken, dass dein wget Beispiel auch MÜLL ist

      sorry aber das musste ich schreiben

  1. Bei der erwähnten Installation war es so in der Crontab drin, hat aber trotzdem zu hunderten von wp-cron.php-Dateien geführt. Die Option „-O /dev/null“ hat bei mir nicht funktioniert, aber mit „–quiet“ sieht es jetzt gut aus.

  2. Wenn der job über die shell gestartet wird, kann man auch php-cli verwenden sofern es installiert ist, was die Regel sein sollte. Also stattedessen:

    */15 * * * * php /pfad/zum/wordpress/wp-cron.php

    1. Danke für die Ergänzung. Funktioniert aber nicht immer.

      Wenn ein Plugin Daten aus dem Request abfragen möchte – den es in dem Fall nicht gibt – kann das möglicherweise zu einem Abbruch führen. Die anstehenden Jobs werden dann nicht ausgeführt. Genau damit bin ich selbst schon einmal auf die Nase gefallen. Mit wget ist man auf der sicheren Seite, weil so ein Request an den Webserver gesendet wird. Damit verhält sich WP genauso als würde der Aufruf über einen Browser erfolgen. Ich würde deshalb immer wget verwenden. Sonst könnte es passieren, dass nach der Installation eines neuen Plugins oder nach einem Plugin-Update evtl. der Cron nicht mehr läuft und es dauert dann vielleicht einige Zeit, bis man das bemerkt…

      LG
      Peter

  3. Wenn man ohnehin mit dem Linux-Cron arbeitet, ist es dann nicht besser, den cronjob in die admin-ajax.php zu legen? Dann spart man sich die Cronverwaltung über WordPress, definiert im Linux-Cron gleich den gewünschten Intervall, und das Ding läuft.
    Habe das so bei einigen Jobs schon so umgesetzt, die unabhängig von der Besucherfrequentz laufen müssen.
    Funktioniert problemlos.

    1. Kann man schon machen, „besser“ finde ich es allerdings nicht. Mit dem Aufrufen der wp-cron.php stellst Du sicher, dass alle registrierten WP Cronjobs ausgeführt werden. WordPress bringt von sich aus schon einige Cronjobs mit, die nicht laufen würden, wenn Du die wp-cron.php nicht aufrufst. Ebenso registrieren auch einige Plugins Cronjobs. Mit dem Aufrufen der wp-cron.php per Linux-Cron stellst Du sicher, dass alle WP Cron Jobs unabhängig von der Besucherfrequenz ausgeführt werden. Wenn Du die wp-cron.php umgehst, dann müsstest Du alle auszuführende Jobs irgendwo eintragen. Ist unnötige Arbeit und muss ständig manuell gewartet werden. Und wenn Du andererseits DISABLE_WP_CRON nicht auf true setzt, damit der WP Cron trotzdem läuft, dann hast Du zwei Stellen, an denen Du Cronjobs verwaltets. Aus meiner Sicht macht das keinen Sinn. Meiner Meinung nach ist es einfach die beste Lösung, nur die wp-cron.php per Cronjob aufzurufen und die Verwaltung der Cronjobs in WP zu machen. Du hast einen einzigen Linux Cronjob und alles andere in WordPress. In WP kannst Du die Cronjobs komfortabel mit WP Crontrol verwalten. Davon unabhängig solltest Du die admin-ajax.php nicht angreifen. Die gehört zum WordPress Core und kann bei einem Update überschrieben werden.

      Liebe Grüße,
      Peter

  4. Guten Morgen Peter,
    danke für die Tipps und Deine Meinung. Hat was für sich, und ich werde das nochmal überdenken.
    Zur admin-ajax.php: Die fasse ich gar nicht an, die Crons übergebe ich mit einem action-Parameter, der WP-Core bleibt natürlich unverändert.
    VG
    Rudi

    1. Hallo Rudi,

      alles klar, dann ist es gut. Interessante Variante. Daran habe ich noch nie gedacht. So ist es auch eine saubere Lösung. Echte Vorteile hat es aber eben aus meiner Sicht nicht.

      Liebe Grüße,
      Peter

      1. Ich habe noch nie überprüft, wie viel Performance von WP beim Aufruf einer Seite benötigt wird, um zu prüfen, ob ein Cron-Job fällig ist oder nicht.
        Ich weiß auch nicht, ob diese Cron-Job-Prüfungen auch beim Aufruf über die admin-ajax.php durchgeführt werden. (Falls ja, ist meine Argumentation im Keller).
        Im konkreten Fall muss ich alle 5 Minuten einen Mailversand-Job durchführen. Der Gedanke ist, dass diese Aufrufe etwas Rechenzeit sparen. Da ich eigene Server betreibe, kann ich das alles relativ leicht einstellen.

        1. Hallo Rudi,

          die Überprüfung erfolgt nachdem die Seite an den Browser ausgeliefert wurde. Das sollte man also nicht merken. Durch Setzen von DISABLE_WP_CRON auf True schaltest Du das ganz komplett aus. Dann rufst Du die wp-cron.php direkt auf. Das ist die sauberste Lösung.

          Liebe Grüße,
          Peter

Schreibe einen Kommentar zu Peter Raschendorfer Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert