Arrêt gracieux
OxPHP gère SIGTERM et SIGINT afin que les requêtes en cours se terminent avant que le processus ne s'arrête. C'est essentiel pour les déploiements sans interruption de service et les mises à jour progressives dans l'orchestration de conteneurs.
Gestion des signaux
OxPHP répond à deux signaux d'arrêt :
| Signal | Source | Comportement |
|---|---|---|
SIGTERM |
Orchestrateurs de conteneurs, docker stop, kill |
Déclenche l'arrêt gracieux |
SIGINT |
Ctrl+C dans le terminal | Déclenche l'arrêt gracieux |
Les deux signaux déclenchent la même séquence d'arrêt. Seul le premier signal est nécessaire. Le serveur commence immédiatement à drainer.
Séquence d'arrêt
À la réception d'un signal d'arrêt, OxPHP suit cette séquence :
- Arrêter d'accepter de nouvelles connexions — le serveur cesse d'accepter de nouvelles connexions TCP sur le port principal. Les workers PHP continuent de tourner pour traiter les requêtes en cours.
- Fermer progressivement les connexions actives — les clients HTTP/2 reçoivent une trame
GOAWAYet les connexions keep-alive HTTP/1.1 inactives sont fermées, de sorte que les clients basculent vers une instance saine au lieu de multiplexer de nouvelles requêtes vers celle qui se termine. Les flux ouverts sont clôturés rapidement et proprement — toute réponse qui a commencé à vider une sortie en chunks compte, aussi bien les téléchargements finis que le SSE — voir Server-Sent Events. - Drainer les requêtes en cours — les requêtes actives ordinaires sont laissées tranquilles jusqu'à ce qu'elles se terminent avec leurs réponses complètes. Le serveur vérifie leur achèvement toutes les 100 ms. Le serveur interne de santé/métriques reste disponible pendant toute la durée du drainage, afin que les sondes de disponibilité continuent de fonctionner.
- Appliquer le délai limite de drainage — les requêtes qui tournent encore après
DRAIN_TIMEOUT_SECONDSsont annulées (leurs callbacksregister_shutdown_function()s'exécutent tout de même) et disposent d'environ 2 secondes pour se terminer avant que le serveur ne poursuive. - Vider les plugins — les entrées de journalisation des accès et les spans APM mis en tampon pendant la fenêtre de drainage sont vidés.
- Arrêter le pool async — le pool de tâches async en arrière-plan est stoppé.
- Interrompre le serveur interne — le serveur de santé/métriques est arrêté une fois le drainage terminé.
- Sortir — le processus se termine avec le code de statut 0.
Les workers PHP sont arrêtés explicitement lors de l'étape 1 — la méthode shutdown() de l'exécuteur est appelée dans le cadre de l'arrêt du serveur principal, ce qui signale aux threads workers de sortir après avoir terminé toute requête en cours.
Configuration
| Variable | Défaut | Description |
|---|---|---|
DRAIN_TIMEOUT_SECONDS |
25 |
Nombre maximum de secondes accordé aux requêtes en cours pour se terminer avant d'être annulées ; le processus se termine dans les ~2 secondes qui suivent le délai limite. La valeur par défaut laisse une marge pour la fin de traitement post-délai et le vidage de la télémétrie dans la période de grâce de terminaison par défaut de 30 secondes de Kubernetes |
Définissez DRAIN_TIMEOUT_SECONDS en fonction de votre requête attendue la plus lente :
- Serveurs d'API avec des réponses rapides :
10–15secondes - Applications avec des envois de fichiers ou des requêtes longues :
30–60secondes - Mode worker avec traitement en arrière-plan : ajustez à votre opération attendue la plus longue
Kubernetes
Sous Kubernetes, le déroulement de l'arrêt lors d'une mise à jour progressive est le suivant :
- Kubernetes envoie
SIGTERMau pod. - Le pod est retiré de la liste des endpoints du Service.
- OxPHP draine les connexions en cours dans le délai de
DRAIN_TIMEOUT_SECONDS, puis annule les retardataires et sort dans les ~2 secondes supplémentaires. - Si le pod tourne encore après
terminationGracePeriodSeconds, Kubernetes envoieSIGKILL.
Fixez terminationGracePeriodSeconds au-dessus de DRAIN_TIMEOUT_SECONDS + 2 pour que le drainage — y compris la fin de traitement post-délai et le vidage de la télémétrie — se termine avant l'arrêt forcé :
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
terminationGracePeriodSeconds: 45
containers:
- name: oxphp
image: ghcr.io/oxphp/oxphp:0.10.0
env:
- name: DRAIN_TIMEOUT_SECONDS
value: "30"Hook pre-stop
Si votre service reçoit du trafic depuis des load balancers externes qui propagent lentement les changements d'endpoints, ajoutez un hook pre-stop pour retarder la séquence d'arrêt :
lifecycle:
preStop:
exec:
command: ["sleep", "5"]Cela laisse au load balancer le temps de retirer le pod de sa liste de cibles avant qu'OxPHP ne cesse d'accepter les connexions.
Docker
Docker envoie SIGTERM lorsque vous lancez docker stop. Le délai d'arrêt par défaut de Docker est de 10 secondes, après quoi Docker envoie SIGKILL.
Pour laisser à OxPHP assez de temps pour drainer, augmentez le délai d'arrêt :
docker stop --time 45 my-oxphp-containerOu définissez-le dans votre fichier Compose :
services:
oxphp:
image: ghcr.io/oxphp/oxphp:0.10.0
stop_grace_period: 45s
environment:
DRAIN_TIMEOUT_SECONDS: "30"Messages de journal
Pendant un arrêt gracieux, OxPHP émet des messages de journal structurés que vous pouvez surveiller :
Drainage réussi :
{"level":"INFO","message":"Received shutdown signal, draining connections"}
{"level":"INFO","message":"Draining in-flight connections","active_connections":3}
{"level":"INFO","message":"All connections drained"}
{"level":"INFO","message":"Server stopped"}Délai limite de drainage atteint :
{"level":"INFO","message":"Received shutdown signal, draining connections"}
{"level":"WARN","message":"Drain timeout reached, cancelling in-flight requests","remaining_connections":1}
{"level":"INFO","message":"All connections drained"}
{"level":"INFO","message":"Server stopped"}Si vous voyez régulièrement l'avertissement « Drain timeout reached », augmentez DRAIN_TIMEOUT_SECONDS ou examinez les requêtes de longue durée à l'aide de l'histogramme oxphp_request_duration_us.
Voir aussi
- Contrôles de santé — sondes de disponibilité et interaction avec l'arrêt
- Référence de configuration — toutes les variables d'environnement, dont
DRAIN_TIMEOUT_SECONDS - Métriques —
oxphp_active_connectionssuit les connexions pendant le drainage