und Cache-Warmup zusammendenken
Der Symlink-Switch ist nur der Anfang. Suchindex-Reindex, Queue-Consumer-Neustart und Cache-Warmup sind die drei verborgenen Wartezeiten nach jedem Magento-Deployment – und sie müssen in der Pipeline koordiniert werden.
Inhaltsverzeichnis
- 1. Die drei verborgenen Downtime-Quellen nach dem Deploy
- 2. Suchindex: Warum Reindex nicht immer sofort nötig ist
- 3. Reindex kontrolliert in die Pipeline einbauen
- 4. Queue-Consumer: Pause, Drain und sicherer Neustart
- 5. Queue-Consumer in der GitLab-Pipeline steuern
- 6. Cache-Warmup: Strategie für die wichtigsten Seiten
- 7. Cache-Warmup automatisiert in der Verify-Stage
- 8. Timing: Reihenfolge der Post-Deploy-Schritte
- 9. Koordiniert vs. unkoordiniert: direkter Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Die drei verborgenen Downtime-Quellen nach dem Deploy
Der Symlink-Switch in Magento-Deployments ist atomar und dauert Millisekunden. Wer danach annimmt, das Deployment sei abgeschlossen, übersieht drei Schichten, die den Unterschied zwischen einer guten Nutzererfahrung und sichtbaren Degradierungen ausmachen. Die erste Schicht ist der Suchindex: Nach einem Deployment mit Schema-Änderungen in OpenSearch oder Elasticsearch muss der Index neu aufgebaut werden. Bis das abgeschlossen ist, können Suchergebnisse unvollständig oder fehlerhaft sein.
Die zweite Schicht sind die Queue-Consumer. Magento nutzt Message Queues über RabbitMQ oder die MySQL-basierte Fallback-Implementierung für asynchrone Verarbeitung: Bestellbestätigungen, Indexer-Updates, Newsletter-Versand, Preisberechnungen. Queue-Consumer, die während des Deployments laufen, arbeiten mit dem alten Code. Nach dem Symlink-Switch müssen sie neu gestartet werden, damit sie den neuen Code verwenden. Ohne kontrollierten Neustart können Queue-Consumer minuten- oder stundenlang mit dem alten Code laufen – oder abstürzen, wenn der alte Code mit der neuen Datenbank inkompatibel ist.
Die dritte Schicht ist der Cache-Warmup. Nach einem Cache-Flush antwortet Magento auf die ersten Requests langsamer, weil alle Caches kalt sind. Bei hoher Last kann das zu spürbaren Latenzspitzen führen, die in Monitoring-Systemen als Incident erscheinen, obwohl das Deployment selbst fehlerfrei war. Ein koordinierter Cache-Warmup nach dem Deployment verhindert diese Latenzspitzen, indem wichtige Seiten vorab aufgerufen und gecacht werden.
2. Suchindex: Warum Reindex nicht immer sofort nötig ist
Nicht jeder Reindex muss unmittelbar nach dem Deployment ausgeführt werden. Magento unterscheidet zwischen verschiedenen Indexer-Typen mit unterschiedlichen Auswirkungen. Ein Reindex des Produktkatalogs ist oft zeitaufwändig – bei großen Katalogen kann er Stunden dauern. Wenn das Deployment keine Änderungen am Katalogsschema oder an der Suchkonfiguration enthält, ist ein vollständiger Reindex nicht notwendig.
Die wichtige Unterscheidung: Partielle Indexer-Updates (indexer:reindex catalogsearch_fulltext) sind häufig deutlich schneller als ein vollständiger Reindex aller Indexer. Für Deployments ohne Schema-Änderungen reicht es, die Indexer im Modus Update by Schedule laufen zu lassen, der Änderungen asynchron verarbeitet. Die Entscheidung, welche Indexer nach welchem Deployment neu aufgebaut werden müssen, sollte im Deployment-Prozess dokumentiert und nicht ad hoc getroffen werden.
3. Reindex kontrolliert in die Pipeline einbauen
Ein Reindex-Job in der GitLab-Pipeline läuft idealerweise als asynchroner Schritt nach dem Symlink-Switch, aber vor dem Verify-Job. Er sollte über eine Variable gesteuert werden, die pro Deployment gesetzt werden kann. So können Releases ohne Schema-Änderungen den Reindex-Job überspringen, während Releases mit Elasticsearch-Mappingänderungen ihn zwingend auslösen.
# Controlled search index rebuild after deployment
reindex:search:
stage: verify
variables:
# Set FORCE_REINDEX=1 for deployments with catalog schema changes
FORCE_REINDEX: "0"
script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
- |
if [ "$FORCE_REINDEX" = "1" ]; then
ssh "$DEPLOY_USER@$DEPLOY_HOST" bash -s << 'SSH'
set -euo pipefail
cd "$DEPLOY_PATH/current"
# Rebuild only the search index — not all indexers
bin/magento indexer:reindex catalogsearch_fulltext
echo "Search index rebuild complete"
# Verify index status
bin/magento indexer:status catalogsearch_fulltext
SSH
else
echo "FORCE_REINDEX not set — skipping full reindex"
echo "Invalidating search cache only"
ssh "$DEPLOY_USER@$DEPLOY_HOST" \
"cd $DEPLOY_PATH/current && bin/magento cache:clean full_page"
fi
needs:
- deploy:production
when: on_success
only:
- tags
4. Queue-Consumer: Pause, Drain und sicherer Neustart
Queue-Consumer müssen während eines Deployments kontrolliert behandelt werden. Das naive Vorgehen – einfach weiterlaufen lassen – führt dazu, dass Consumer nach dem Symlink-Switch mit dem neuen current-Verzeichnis arbeiten, aber PHP-Prozesse, die bereits gestartet wurden, noch auf den alten Code zugreifen. Das ist besonders kritisch bei Deployments mit Datenbankmigrationen: Ein alter Queue-Consumer kann versuchen, mit dem alten Schema-Zustand Daten zu schreiben, die das neue Schema erwartet.
Das sichere Muster: Vor dem Symlink-Switch die Queue-Consumer stoppen oder pausieren (bin/magento queue:consumers:stop), nach dem Switch neu starten. Der Drain-Schritt stellt sicher, dass alle aktuell verarbeiteten Nachrichten abgeschlossen werden, bevor die Consumer gestoppt werden. Das vermeidet verloren gegangene Nachrichten. Bei RabbitMQ-basierten Setups kann die Queue weiter Nachrichten empfangen, während die Consumer gestoppt sind – sie werden nach dem Neustart verarbeitet, was Queue-Lag erzeugt, aber keine verlorenen Nachrichten.
5. Queue-Consumer in der GitLab-Pipeline steuern
Die Steuerung der Queue-Consumer gehört in den Deploy-Job, nicht in ein manuelles Betriebshandbuch. Ein Deploy-Job, der Queue-Consumer nicht behandelt, ist für Deployments mit Datenbankmigrationen unvollständig. Der folgende YAML-Block zeigt das sichere Muster für Queue-Consumer-Verwaltung im Deployment-Kontext.
# Queue consumer management integrated into the deploy job
deploy:production:
stage: deploy
script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
- RELEASE_ID=$(date +%Y%m%d-%H%M%S)
- RELEASE_PATH="$DEPLOY_PATH/releases/$RELEASE_ID"
# Transfer artifact to new release directory
- ssh "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p $RELEASE_PATH"
- rsync -az --delete ./ "$DEPLOY_USER@$DEPLOY_HOST:$RELEASE_PATH/"
- |
ssh "$DEPLOY_USER@$DEPLOY_HOST" bash -s << 'SSH'
set -euo pipefail
# Stop queue consumers before symlink switch (prevents old-code processing)
# This command requires Magento 2.4+ with queue:consumers:stop support
cd "$DEPLOY_PATH/current"
bin/magento queue:consumers:stop --wait-for-running-processes || true
# Link shared resources and switch symlink atomically
RELEASE_PATH="$DEPLOY_PATH/releases/$RELEASE_ID"
ln -sfn "$DEPLOY_PATH/shared/app/etc/env.php" "$RELEASE_PATH/app/etc/env.php"
ln -sfn "$DEPLOY_PATH/shared/pub/media" "$RELEASE_PATH/pub/media"
ln -sfn "$RELEASE_PATH" "$DEPLOY_PATH/current"
# Post-switch: flush cache and restart consumers with new code
cd "$DEPLOY_PATH/current"
bin/magento cache:flush
# Restart queue consumers — systemd or supervisor depending on setup
systemctl restart magento-queue-consumers || supervisorctl restart magento:*
SSH
when: manual
only:
- tags
6. Cache-Warmup: Strategie für die wichtigsten Seiten
Ein Cache-Flush ohne anschließenden Warmup hinterlässt ein Magento-System mit vollständig kaltem Cache. Die ersten Requests nach dem Deployment treffen auf unkonditionierte PHP-Prozesse, die alle Caches neu aufbauen müssen: Block-Cache, Layout-Cache, Config-Cache, Full-Page-Cache. Dieser Zustand dauert typischerweise mehrere Minuten bei einem mittelgroßen Shop. In dieser Zeit sind Ladezeiten deutlich erhöht und können zu Abbrüchen bei Nutzern führen.
Die Warmup-Strategie priorisiert Seiten nach ihrer Bedeutung: Startseite, wichtigste Kategorieseiten, meistbesuchte Produktseiten. Ein einfaches Warmup-Skript ruft diese Seiten per curl auf und erzwingt so die Cache-Generierung. Fortgeschrittene Implementierungen nutzen Magento-native Tools wie bin/magento cache:warm oder externe Cache-Warming-Services wie Varnish-Warming-Scripts. Der Warmup sollte in der Verify-Stage nach dem Deploy-Job ausgeführt werden, sobald der Health-Check bestätigt hat, dass das neue Release antwortet.
7. Cache-Warmup automatisiert in der Verify-Stage
Der Cache-Warmup in der GitLab-Pipeline ist ein Verify-Stage-Job, der nach dem erfolgreichen Deployment die wichtigsten URLs aufruft. Die URL-Liste sollte als Variable oder als Datei im Repository verwaltet werden, damit sie einfach aktualisiert werden kann, wenn sich die Seitenstruktur des Shops ändert. Ein Warmup-Job, der die falschen Seiten aufruft, ist nutzlos; einer, der die richtigen Seiten aufruft, reduziert Post-Deployment-Latenz messbar.
# Cache warmup job — runs after successful deployment verification
warmup:cache:
stage: verify
variables:
SHOP_BASE_URL: "https://shop.mironsoft.de"
WARMUP_TIMEOUT: "30"
script:
# Health check first — only warm cache if site responds
- curl -f --max-time 10 "$SHOP_BASE_URL/health" || exit 1
# Warm the most important pages sequentially
- |
PAGES=(
"/"
"/sale.html"
"/herren.html"
"/damen.html"
"/neuheiten.html"
"/customer/account/login"
"/checkout/cart"
)
for page in "${PAGES[@]}"; do
echo "Warming: $SHOP_BASE_URL$page"
curl -s -o /dev/null -w "%{http_code} %{time_total}s" \
--max-time "$WARMUP_TIMEOUT" \
-H "X-Cache-Warmup: 1" \
"$SHOP_BASE_URL$page" || true
echo ""
done
# Verify full page cache is now active
- |
CACHE_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
--max-time 10 "$SHOP_BASE_URL/")
echo "Homepage status after warmup: $CACHE_STATUS"
[ "$CACHE_STATUS" = "200" ] || exit 1
needs:
- deploy:production
when: on_success
only:
- tags
8. Timing: Reihenfolge der Post-Deploy-Schritte
Die Reihenfolge der Post-Deploy-Schritte ist nicht beliebig. Queue-Consumer müssen vor dem Symlink-Switch gestoppt werden, damit sie keine alten Nachrichten mit dem neuen Code oder neuen Nachrichten mit dem alten Code verarbeiten. Der Symlink-Switch selbst ist der atomare Kern des Deployments. Unmittelbar danach folgt der Cache-Flush, der alle Magento-Caches leert. Dann kommt der Queue-Consumer-Neustart mit dem neuen Code. Erst wenn die Consumer laufen und der Health-Check grün ist, kann der Cache-Warmup beginnen.
Der Reindex sollte nach dem Cache-Warmup und nach dem Queue-Consumer-Neustart ausgeführt werden, da er I/O-intensiv ist und Konkurrenz mit dem Warmup-Traffic vermieden werden sollte. Ein vollständiger Reindex kann je nach Kataloggröße Minuten bis Stunden dauern und sollte deshalb außerhalb der Stoßzeiten oder in einem separaten, manuell ausgelösten Job geplant werden. Die klare Reihenfolge dieser Schritte ist der Unterschied zwischen einem koordinierten und einem improvisierten Post-Deploy-Prozess.
9. Koordiniert vs. unkoordiniert: direkter Vergleich
Der Unterschied zwischen einem koordinierten und einem unkoordinierten Post-Deploy-Prozess zeigt sich nicht sofort, sondern in den Stunden nach einem Deployment. Unkoordinierte Prozesse hinterlassen sichtbare Lücken: Suchergebnisse zeigen veraltete Daten, Queue-Consumer verarbeiten Nachrichten mit dem falschen Code, Nutzer bemerken deutlich erhöhte Ladezeiten. Koordinierte Prozesse schließen diese Lücken systematisch.
| Post-Deploy-Aspekt | Unkoordiniert | Koordiniert (GitLab-Pipeline) | Auswirkung |
|---|---|---|---|
| Suchindex | Manuell oder vergessen | Pipeline-Job mit Variable | Saubere Suchergebnisse ab Minute 1 |
| Queue-Consumer | Laufen mit altem Code weiter | Stop vor Switch, Start danach | Keine Schema-Inkompatibilitäten |
| Cache-Warmup | Nutzer wärmen den Cache auf | Automatisch nach Verify | Keine Latenzspitzen nach Deploy |
| Reindex-Timing | Gleichzeitig mit Warmup | Nach Warmup, außerhalb Stoßzeit | Geringere Server-Last |
| Fehlerdiagnose | Keine Log-Struktur | Pipeline-Logs je Schritt | Schnelle Ursachenanalyse |
Die Investition in koordinierte Post-Deploy-Schritte ist überschaubar. Die drei Jobs – Reindex, Queue-Consumer-Neustart und Cache-Warmup – können in wenigen Stunden in eine bestehende Pipeline integriert werden. Die Einsparungen in Form von vermiedenen Incidents, kürzeren Latenzspitzen und schnellerer Fehlerdiagnose übersteigen den Aufwand bei der ersten Produktion-Nutzung.
10. Zusammenfassung
Zero-Downtime bei Suchindex, Queue-Lag und Cache-Warmup zusammendenken bedeutet, den Deployment-Prozess über den Symlink-Switch hinaus zu denken. Der Switch selbst ist der schnellste Schritt; die drei Post-Deploy-Schichten sind die eigentliche Herausforderung. Suchindex-Reindex muss pro Deployment bewusst entschieden werden – nicht immer notwendig, aber wenn, dann koordiniert. Queue-Consumer müssen vor dem Switch gestoppt und danach mit dem neuen Code neu gestartet werden. Cache-Warmup verhindert Latenzspitzen nach dem Deploy und schützt die Nutzererfahrung in den ersten Minuten nach dem Release.
In der GitLab-Pipeline werden diese drei Schritte als Jobs in der Verify-Stage implementiert, die nach dem erfolgreichen Deploy-Job laufen. Jeder Job ist einzeln konfigurierbar, einzeln beobachtbar und einzeln debuggbar. Das ist der Unterschied zwischen einem Deployment-Prozess, der beim Symlink-Switch endet, und einem, der erst dann abgeschlossen ist, wenn der Shop vollständig und performant antwortet.
Zero-Downtime: Suchindex, Queue und Cache — Das Wichtigste auf einen Blick
Suchindex
Nicht nach jedem Deploy nötig. FORCE_REINDEX-Variable steuert, ob catalogsearch_fulltext neu aufgebaut wird.
Queue-Consumer
Stoppen vor dem Symlink-Switch, neu starten danach. Verhindert Schema-Inkompatibilitäten bei Datenbankmigrationen.
Cache-Warmup
Nach Verify-Health-Check die wichtigsten Seiten vorab aufrufen. Verhindert Latenzspitzen in den ersten Minuten nach dem Deploy.
Reihenfolge
Consumer stoppen → Symlink-Switch → Cache-Flush → Consumer starten → Health-Check → Warmup → Reindex (bei Bedarf).