Logo run_as_root - Magento B2B Agentur Würzburg

Cron Jobs in Magento 2: Zeitpläne und Gruppen anpassen

Technical
Cron Jobs in Magento 2: Zeitpläne und Gruppen anpassen

Inhalte

In diesem Artikel behandle ich ein Thema, das zwar nicht besonders komplex ist, ohne ein paar hilfreiche Tipps aber ganz schön nervig werden kann. Konkret schauen wir uns Magento 2 (Mage-OS / Adobe Commerce) an – genauer gesagt Cron Jobs, ihre Konfiguration sowie den Prozess zum Umplanen und zur Änderung ihrer Ausführungsgruppe.

Du fragst dich vielleicht: Warum sollte ich überhaupt den Zeitplan oder die Gruppe eines Cron Jobs ändern? Lass es uns herausfinden.

Warum den Cron-Zeitplan anpassen?

Manchmal läuft ein Cron Job zu häufig und verursacht dadurch Serverauslastung oder sogar Deadlocks. Andererseits kann es passieren, dass er zu selten läuft – und du dann stundenlang auf E-Mails wartest. Diese Situation wird besonders heikel, wenn es sich um Cron Jobs von Drittanbieter-Extensions handelt.

Stell dir vor, du nutzt Drittanbieter-Extensions für einen Feed und ein Mailing-System und bist mit deren Cron-Job-Zeitplänen nicht zufrieden.

Wie kannst du die Ausführungsintervalle dieser Cron Jobs ändern, ohne direkt am Code der Drittanbieter zu arbeiten? Indem du die Änderungen in deiner eigenen Codebasis – deinem eigenen Modul – umsetzt. Schauen wir uns das genauer an.

Cron Jobs umplanen

Werfen wir einen Blick auf den Cron Job der Feed-Extension: feed_generation.

So sieht seine Definition aus:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="default">
        ...
        <job name="feed_generation" instance="\Feed\Cron\FeedGenerator" method="execute">
            <schedule>* * * * *</schedule>
        </job>
        ...
    </group>
</config>

Dieser Job läuft jede Minute und kann die Serverlast erheblich erhöhen. Einen neuen Feed alle 60 Sekunden braucht wirklich niemand!

Um das Intervall zu ändern, erstellen wir ein Modul namens Devto_ChangeFeedSchedule und legen darin eine etc/config.xml an.

Die Modulstruktur sieht so aus:

Devto_ChangeFeedSchedule/
│
├── etc/
│   ├── config.xml      # unsere Konfigurationsdatei
│   └── module.xml
│
├── registration.php
│
└── composer.json

Die etc/config.xml sollte folgenden Inhalt haben:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <crontab>
            <default> <!-- Cron-Gruppe -->
                <jobs>
                    <feed_generation> <!-- Job-Name -->
                        <schedule>
                            <cron_expr>0 * * * *</cron_expr> <!-- neuer Cron-Ausführungszeitplan -->
                        </schedule>
                    </feed_generation>
                </jobs>
            </default>
        </crontab>
    </default>
</config>

Nicht vergessen: Trage in der etc/module.xml die Abhängigkeit zur Feed-Extension ein, damit die Konfigurationen in der richtigen Reihenfolge angewendet werden:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Devto_ChangeFeedSchedule">
        <sequence>
            <!-- sorgt dafür, dass die Configs von Devto_ChangeFeedSchedule nach der Feed-Extension angewendet werden -->
            <module name="Vendor_FeedExtesnion"/>
        </sequence>
    </module>
</config>

Sobald das Modul Devto_ChangeFeedSchedule aktiviert und der Cache geleert wurde, greift der neue Zeitplan – der Job läuft dann stündlich statt jede Minute.

Aber was ist mit Cron-Gruppen? Schauen wir uns das als Nächstes an.

Warum die Cron-Gruppe ändern?

Stell dir vor, du arbeitest weiterhin mit den Drittanbieter-Extensions für Feed und Mailing. Diese Extensions nutzen eigene Cron-Gruppen, die jeweils als isolierter Prozess laufen. Dadurch können Cron-Gruppen parallel ausgeführt werden.

Angenommen, diese beiden Cron Jobs kollidieren und verursachen Dateninkonsistenzen in Feed und E-Mails. Schlimmer noch: Es können Deadlocks entstehen. Du fragst dich vielleicht: „Wie kommt es zu Deadlocks?"

Ganz einfach: Stell dir vor, beide Extensions lesen und schreiben in dieselbe Tabelle, z. B. sales_order_item. Wenn sie gleichzeitig laufen, ist der Grundstein für potenzielle Deadlocks gelegt. 🤷‍♂️

Wenn die Jobs doch nur nacheinander laufen würden! Indem du sie in eine gemeinsame Gruppe verschiebst, stellst du sicher, dass sie nicht mehr parallel ausgeführt werden.

Die Cron-Gruppe eines Jobs ändern

Eine einfache (wenn auch nicht perfekte) Lösung wäre es, den Cron Job der Mailing-Extension in die default-Gruppe zu verschieben, in der auch der Feed-Job liegt. So sieht die Definition des Mailing-Cron-Jobs aus:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="mailing_extension"> <!-- Mailing-Cron-Gruppe -->
        ...
        <job name="send_mails_from_mailing_extension"
             instance="\Mailing\Cron\SendMailsCron" method="execute">
            <schedule>*/20 * * * *</schedule>
        </job>
        ...
    </group>
</config>

Hier ist jedoch ein kleiner, nicht intuitiver Trick entscheidend: Die Gruppe lässt sich nicht einfach durch eine neue Definition in der crontab.xml überschreiben. Stattdessen musst du einen neuen Cron Job erstellen und den alten deaktivieren – denn crontab.xml-Konfigurationen (insbesondere Gruppen) lassen sich nur erweitern, nicht überschreiben.

Würdest du send_mails_from_mailing_extension einfach in der default-Gruppe definieren, würde er in beiden Gruppen laufen – also sowohl in default als auch in mailing_extension.

Um send_mails_from_mailing_extension zu deaktivieren, gibt es einen einfachen Trick: Plane ihn auf den 30. Februar – ein Datum, das es nicht gibt!

🤓

Nerd-Fakt: Den 30. Februar gab es tatsächlich – in Schweden im Jahr 1712.

Wie zuvor beschrieben fügen wir folgenden Inhalt zur etc/config.xml unseres Moduls Devto_ChangeMailingJobGroup hinzu:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <crontab>
            <default>
                <jobs>
                    <!-- Cron-Ausführung deaktivieren, indem er auf den 30. Feb. geplant wird. -->
                    <send_mails_from_mailing_extension>
                        <schedule>
                            <cron_expr>0 0 30 2 *</cron_expr>
                        </schedule>
                    </send_mails_from_mailing_extension>
                </jobs>
            </default>
        </crontab>
    </default>
</config>

Als Nächstes definieren wir einen NEUEN Cron Job in der default-Gruppe:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="default"> <!-- default Cron-Gruppe -->
        ...
        <!-- devto-Präfix zum Cron-Namen hinzugefügt -->
        <job name="devto_send_mails_from_mailing_extension"
             instance="\Mailing\Cron\SendMailsCron" method="execute">
            <schedule>*/20 * * * *</schedule>
        </job>
        ...
    </group>
</config>

Und vergiss nicht, die Mailing-Module-Sequenz in die etc/module.xml einzutragen:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Devto_ChangeMailingJobGroup">
        <sequence>
            <!-- sorgt dafür, dass die Configs von Devto_ChangeMailingJobGroup nach der Mailing-Extension angewendet werden -->
            <module name="Vendor_MailingExtesnion"/>
        </sequence>
    </module>
</config>

Nach allen Änderungen sieht die Modulstruktur so aus:

Devto_ChangeMailingJobGroup/
│
├── etc/
│   ├── config.xml      # unsere Konfigurationsdatei
│   ├── crontab.xml     # unsere Crontab-Definitionsdatei
│   └── module.xml
│
├── registration.php
│
└── composer.json

Sobald Devto_ChangeMailingJobGroup aktiv und der Cache geleert ist, wird der Job send_mails_from_mailing_extension deaktiviert. Dafür läuft sein Pendant, devto_send_mails_from_mailing_extension, nun in der default-Cron-Gruppe zusammen mit dem Feed-Cron-Job.

Ein Wort zur Vorsicht bei der Default-Gruppe

Bedenke, dass Magento die default-Cron-Gruppe bereits mit nativen Jobs gut ausgelastet. Überfüllst du sie, kann es zu „Staus" kommen – vor allem dann, wenn:

  • Jobs lange laufen: Wenn deine Aufgaben zu viel Zeit in Anspruch nehmen, müssen sie in der Warteschlange stehen und verlangsamen das gesamte System.
  • Jobs zu häufig geplant sind: Zu kurze Intervalle führen zu Rückstaus und potenziellen Überschneidungen.
  • Zu viele Jobs vorhanden sind: Selbst schnelle Aufgaben können das System überlasten, wenn es zu viele davon gibt.

Die Default-Gruppe ist praktisch – aber stell dir sie wie eine Hauptverkehrsstraße zur Stoßzeit vor. Sie kann viel bewältigen, aber irgendwann ist auch sie überlastet. Zu viele schwere Aufgaben oder zu kurze Intervalle führen zwangsläufig zu Verzögerungen.

Kurz gesagt: Sei dir der Auslastung der default-Gruppe bewusst und erwäge, eigene Cron-Gruppen zu erstellen, um Prozesskonflikte zu vermeiden.

Fazit

Das war ein Überblick über Magento-Cron-Jobs – wie du ihre Zeitpläne änderst und Gruppen anpasst, ohne direkt in den Code von Drittanbietern einzugreifen. Mit diesem Wissen sollte das Anpassen lästiger Cron Jobs deutlich einfacher werden 😊

Vielen Dank fürs Lesen!


Image from Enrico Da Prato on Unsplash

Deine Magento 2 Cron Jobs optimieren?

Sprich mit Vladyslav, unserem Magento-Experten, und verbessere die Performance deines Shops durch die Feinabstimmung von Cron-Job-Zeitplänen und -Gruppen.

Buche jetzt deinen Termin

Weitere Beiträge

Technical
/images/blog/blog_INP_corewebvitals_thumbnail.webp
Jordy Scholing Avatar

Jordy Scholing

14.11.25

INP debuggen: Von DevTools zu RUM-Daten