CV laden
Zurück zu Business Cases

Deploy

SIGTERM mitten im Katalog-Write

compose restart php tötete FCGI im Flug. nginx lieferte 502. Ein halb geschriebener Memcached-Key blieb.

Ein Deploy ist docker compose up -d --build php. Der alte Container bekommt SIGTERM. PHP-FPM hat ein paar Sekunden, dann SIGKILL. Ein Worker, der einen Listen-Slab schrieb, stoppte. nginx lieferte 502. Memcached behielt einen abgeschnittenen Wert. Der nächste GET diente kaputtes HTML, bis der Rebuild-Lock wieder lief.

opcache_reset() in einem Hook machte die nächste Minute schlimmer. Jeder überlebende Worker kompilierte LaraBoom gleichzeitig. CPU sprang. Die Liste, die gerade 502 hatte, wartete auf Compile.

Das Problem war, einen Container-Restart als Drain zu behandeln. Besucher bekamen 502 und dann einen kaputten Slab. Ich brauchte SIGUSR2 in einem lebenden Container, eine Grace-Periode länger als der langsamste Request und kein geteiltes opcache_reset().

SIGTERM ist kein Drain. SIGUSR2 ist einer. FCGI im Flug muss enden.
SIGTERM ist kein Drain. SIGUSR2 ist einer. FCGI im Flug muss enden.

Reload im Container

Das Image kopiert zuerst Code. Dann kill -USR2 auf die php-fpm-PID. Alte Worker beenden den Request. Neue starten mit den neuen Dateien und Preload. nginx behält den Unix-Socket. Es gibt keinen 502 durch totes FCGI auf diesem Pfad. Memcached-Writes enden. Der Rebuild-Lock in Redis bleibt nicht halb gehalten.

Ein neuer Worker hat einen neuen OPcache. Ein geteiltes Reset ist ein Stampede mit Absicht.
Ein neuer Worker hat einen neuen OPcache. Ein geteiltes Reset ist ein Stampede mit Absicht.
  • stop_grace_period am php-Dienst ist länger als der langsamste Katalog-Request, den wir gemessen haben.
  • queue und schedule bekommen ein eigenes neues Image. Ein Horizon-Worker beendet den aktuellen Job und stirbt.
  • Memcached SET eines Slabs ist ein Wert. Teilwrites passieren nicht, wenn der Prozess bis zum SET-Return lebt.

Deploys dauern weiter eine Minute wegen des Image-Builds. Die öffentliche Seite liefert in dieser Minute kein 502. Das war die Anforderung.

Was ich daraus mitnehme

compose restart ist kein Rolling Reload. SIGTERM dann SIGKILL schneidet FCGI. SIGUSR2 ist der Drain, den PHP-FPM schon hat.

opcache_reset() auf einem lebenden Pool ist ein Compile-Stampede. Neue Worker bekommen einen neuen Cache. Alte sollen enden und sterben.

Ein abgeschnittener Memcached-Wert ist schlimmer als 502. SET zu Ende führen oder nicht starten.

Zurück zu Business Cases