Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Eigene Cron-Gruppe (Crongroup) definieren: crontab.xml

Eigene Cron-Gruppe (Crongroup) definieren: crontab.xml

~7 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Kapitel 33 braucht einen täglichen Cronjob, der Punkte verfallen lässt. Bevor dieser Job existiert, klärt dieses Kapitel eine Design-Frage: läuft er in der Standard-Crongroup default mit, in der auch Indexierung, E-Mail-Versand und Dutzende Core-Jobs stecken - oder in einer eigenen, isolierten Gruppe? Laut Spezifikation: eine eigene Gruppe, ID mironsoft_loyalty.

Warum eine eigene Gruppe?

  • Isolation: ein langsamer oder hängender Job in default kann - je nach Konfiguration - die Verarbeitung anderer default-Jobs verzögern. Eine eigene Gruppe trennt das Treueprogramm vom Rest.
  • Eigene Zeitplan-Historie: history_success_lifetime/history_failure_lifetime lassen sich je Gruppe unterschiedlich konfigurieren - ein täglicher Job braucht andere Aufbewahrungszeiten als ein minütlicher.
  • Eigener Prozess möglich: das optionale <use_separate_process>-Flag lässt cron:run diese Gruppe in einem eigenen Subprozess ausführen.

etc/crontab.xml

app/code/Mironsoft/Loyalty/etc/crontab.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="mironsoft_loyalty">
        <job name="mironsoft_loyalty_expire_points"
             instance="Mironsoft\Loyalty\Cron\ExpirePoints"
             method="execute">
            <config_path>mironsoft_loyalty/cron/expire_points_schedule</config_path>
        </job>
    </group>
</config>

<config_path> statt eines fest verdrahteten <schedule>-Cron-Ausdrucks: Magento liest den Cron-Ausdruck damit aus einem Konfigurationswert - dem genau in der Spezifikation geforderten "eigenen cron_run_frequency". Ein Shop-Betreiber kann den Ausführungszeitpunkt so später über Stores > Konfiguration ändern, ohne eine neue Modulversion zu benötigen.

Der passende Konfigurationswert

Kapitel 7 legte die vier Pfade unter mironsoft_loyalty/general/* fest. Dieses Kapitel ergänzt eine neue Gruppe cron in system.xml mit einem fünften Konfigurationspfad, mironsoft_loyalty/cron/expire_points_schedule.

<!-- Ergänzung in app/code/Mironsoft/Loyalty/etc/adminhtml/system.xml,
     innerhalb der bestehenden <section id="mironsoft_loyalty"> aus Kapitel 7 -->
<group id="cron" translate="label" sortOrder="20"
       showInDefault="1" showInWebsite="0" showInStore="0">
    <label>Cron Settings</label>
    <field id="expire_points_schedule" translate="label,comment" type="text" sortOrder="10"
           showInDefault="1" showInWebsite="0" showInStore="0">
        <label>Expire Points Cron Expression</label>
        <comment>Standard cron syntax, e.g. "0 2 * * *" for daily at 2am.</comment>
    </field>
</group>
<!-- Ergänzung in app/code/Mironsoft/Loyalty/etc/config.xml,
     innerhalb von <default><mironsoft_loyalty> aus Kapitel 7 -->
<cron>
    <expire_points_schedule>0 2 * * *</expire_points_schedule>
</cron>

Gruppen-eigene Laufzeit-Einstellungen

Wie oft der Schedule-Generator vorausplant, wie lange ein geplanter Lauf gültig bleibt und wie lange die Historie aufbewahrt wird, konfiguriert Magento pro Gruppe unter system/cron/<group_id>/* - ergänzt in config.xml, nicht in crontab.xml.

<!-- Weitere Ergänzung in app/code/Mironsoft/Loyalty/etc/config.xml -->
<system>
    <cron>
        <mironsoft_loyalty>
            <schedule_generate_every>60</schedule_generate_every>
            <schedule_ahead_for>120</schedule_ahead_for>
            <schedule_lifetime>180</schedule_lifetime>
            <history_cleanup_every>60</history_cleanup_every>
            <history_success_lifetime>4320</history_success_lifetime>
            <history_failure_lifetime>10080</history_failure_lifetime>
        </mironsoft_loyalty>
    </cron>
</system>

schedule_generate_every steht hier bewusst auf 60 (Minuten) statt des core-üblichen 1: ein einziger täglicher Job braucht keine minütliche Schedule-Generierung. history_success_lifetime ist mit drei Tagen (4320 Minuten) kürzer als bei vielen Core-Gruppen, weil die eigentliche Historie bereits dauerhaft im Punkte-Ledger (Kapitel 3) steht - die cron_schedule-Tabelle muss hier nur kurzfristig zur Fehlersuche dienen.

Achtung: Der Cron-Ausdruck in <schedule> bzw. dem config_path-Wert wird gegen die konfigurierte Zeitzone (general/locale/timezone, Standard-Scope) ausgewertet - nicht zwangsläufig gegen die Systemzeitzone des Servers. 0 2 * * * bedeutet "02:00 Uhr in der im Shop hinterlegten Zeitzone", was insbesondere bei UTC-Servern und einer auf eine andere Zeitzone eingestellten Shop-Konfiguration zu Verwirrung führt ("warum läuft der Job erst um 4 Uhr Serverzeit?"). Bei einer Änderung von general/locale/timezone verschiebt sich der tatsächliche Ausführungszeitpunkt entsprechend mit - ohne dass der Cron-Ausdruck selbst angefasst wurde.

Den Master-Cron nicht vergessen

Eine neue Crongroup allein reicht nicht - Magentos eigener "Cron über Cron"-Mechanismus (cron:run, setup:cron:run, update:cron:run) muss regelmäßig laufen, damit überhaupt irgendetwas geplant und ausgeführt wird. Im Mark-Shust-Setup dieses Projekts übernimmt das bereits ein eigener Cron-Container - ein Blick hinein bestätigt den Lauf.

# Alle fälligen Jobs aus allen Gruppen ausführen
bin/magento cron:run

# Nur die eigene Gruppe manuell auslösen (z. B. lokal zum Testen)
bin/magento cron:run --group=mironsoft_loyalty

Tipp: --group=mironsoft_loyalty ist nur für manuelles Testen oder eine bewusst separate, eigene Crontab-Zeile auf einem anderen Zeitplan nötig - das Standard-cron:run des Mark-Shust-Cron-Containers deckt ohnehin alle Gruppen ab, inklusive dieser neuen.

Mit Gruppe und Zeitplan an Ort und Stelle folgt in Kapitel 33 die eigentliche Job-Klasse: ExpirePoints.