TCP Keepalive détermine la vitesse à laquelle un serveur détecte et met fin aux sessions TCP inactives - un levier qui a un impact direct sur la consommation de ressources, la latence et le comportement en cas de panne dans le domaine de l'hébergement. Grâce à des valeurs de repos, d'intervalle et de test appropriées, je réduis les connexions en attente, j'évite les interruptions NAT et je maintiens les applications web en état de fonctionnement. Configurations d'hébergement joignable de manière fiable.
Points centraux
- Paramètres: définir de manière ciblée Idle, Intervall, Probes
- Délimitation: TCP Keepalive vs. HTTP Keep-Alive
- Par socket: Overrides par service/pod Kubernetes
- Pare-feu/NAT: Prendre en compte activement les Idle-Timeouts
- Suivimesure, test de charge, réglage fin itératif
Comment fonctionne TCP Keepalive
J'active Keepalive au niveau de la socket ou du système, afin que la pile envoie de petits échantillons à intervalles définis en cas d'inactivité. Après un temps d'attente réglable (Idle), le système envoie le premier test ; ensuite, d'autres probes suivent à un intervalle défini jusqu'à ce que le nombre de tentatives soit atteint. Si le correspondant reste muet, je mets fin à la connexion et j'indique des descripteurs de fichiers ainsi que des tampons dans le Noyau libre. La logique se distingue clairement des retransmissions, car Keepalive vérifie l'état de viabilité d'un flux par ailleurs au repos. Dans les environnements d'hébergement avec de nombreuses sessions simultanées, ce comportement permet d'éviter les fuites insidieuses que je ne constate souvent qu'à un niveau élevé. Dernier de la vie.
Pourquoi Keepalive compte dans l'hébergement
Les clients défectueux, les réseaux mobiles et les passerelles NAT agressives laissent souvent des traces. Connexions zombies, qui restent ouverts longtemps sans Keepalive. Cela coûte des sockets ouverts, de la RAM et du CPU dans les processus d'acceptation, de travail et de proxy, ce qui allonge les temps de réponse. En utilisant des valeurs appropriées, j'élimine rapidement ces cartes et je conserve les écouteurs, les backends et les upstreams. réactif. Sous les pics de charge, l'effet est particulièrement visible, car moins de connexions mortes remplissent les files d'attente. C'est pourquoi je planifie Keepalive en même temps que les temporisations HTTP et TLS et je veille à un cohérent Interaction entre toutes les couches.
Paramètres sysctl : valeurs pratiques
Linux fournit des valeurs par défaut très longues qui ne sont pas utilisées en production. Environnements d'hébergement ne conviennent que rarement. Pour les serveurs web, je fixe généralement une durée d'inactivité nettement plus courte afin de pouvoir évacuer à temps les sessions suspendues. Je maintiens l'intervalle entre les sondes à un niveau modéré afin de pouvoir détecter rapidement les pannes sans pour autant inonder le réseau de vérifications. J'équilibre le nombre de sondes entre les fausses alertes et la durée de détection ; moins de sondes raccourcissent le temps de libération de l'accès. Ressources. Pour IPv6, je tiens compte des variables net.ipv6 respectives et je garde les deux protocoles cohérents.
| Paramètres | Standard (Linux) | Recommandation d'hébergement | Avantages |
|---|---|---|---|
| tcp_keepalive_time | 7200s | 600-1800s | Quand le premier échantillon est envoyé après Idle |
| tcp_keepalive_intvl | 75s | 10-60s | Distance entre les échantillons individuels |
| tcp_keepalive_probes | 9 | 3-6 | Nombre maximum de tentatives infructueuses avant de fermer |
Je définis les valeurs de base pour l'ensemble du système et je les applique de manière permanente via sysctl, afin que les redémarrages n'annulent pas le travail de réglage. En outre, je documente les valeurs de départ et mesure après chaque modification les effets sur Taux d'erreur et les latences. C'est ainsi que je maintiens l'équilibre entre une détection rapide et un trafic réseau supplémentaire. J'utilise souvent les lignes suivantes comme point de départ et je les adapte ensuite par charge de travail :
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 5
sysctl -p
Réglage par socket et par plateforme
Les valeurs par défaut globales me suffisent rarement ; je définis par service Par socket-pour que les backends sensibles vivent plus longtemps, tandis que les frontends nettoient rapidement. En Python, Go ou Java, je règle SO_KEEPALIVE et les options TCP spécifiques directement sur la socket. Sous Linux, je contrôle via TCP_KEEPIDLE, TCP_KEEPINTVL et TCP_KEEPCNT, tandis que Windows fonctionne avec des clés de registre (KeepAliveTime, KeepAliveInterval). Dans Kubernetes, j'écrase les paramètres de manière spécifique au pod ou au déploiement afin de traiter les passerelles API à courte durée de vie différemment des passerelles à longue durée de vie. Base de données-proxys. Pour les configurations de conteneurs, je vérifie également les tables NAT de l'hôte et les plug-ins CNI, car les flux inactifs y sont souvent supprimés plus tôt que je ne le souhaiterais.
# Exemple (Python, Linux)
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
HTTP Keep-Alive vs TCP Keepalive
HTTP Keep-Alive maintient les connexions ouvertes pour plusieurs requêtes, alors que TCP Keepalive fournit de pures vérifications de l'état de vigilance au niveau du transport. Les deux mécanismes se complètent, mais fonctionnent avec des cibles et des temporisateurs différents. Dans HTTP/2 et HTTP/3, les trames PING jouent en partie le rôle de Keepalive, mais je sécurise tout de même la couche TCP. Je règle le délai d'attente HTTP en fonction de l'application, tandis que je règle les valeurs TCP sur la libération économique de l'espace de stockage. Ressources sur le site. Ceux qui souhaitent approfondir les détails sur le site HTTP trouveront un guide utile à ce sujet sous HTTP Keep-Alive Timeout.
Network Timeout Tuning : pratique
Pour les frontaux d'hébergement web classiques, je travaille souvent avec 300s d'inactivité, 30-45s d'intervalle et 4-6 probes pour terminer rapidement les sessions inactives et Files d'attente de rester légers. Les connexions aux bases de données sont plus patientes, afin que les courtes phases d'attente ne déclenchent pas de déconnexion inutile. Dans les passerelles Edge ou API, je raccourcis en outre les délais, car les connexions de courte durée y sont très nombreuses. Je fais correspondre les valeurs avec les délais d'attente TLS, les délais d'attente en lecture/écriture et les délais d'attente en amont afin d'éviter les contradictions aux limites des couches. Pour l'optimisation pas à pas, un tableau compact Tuning-Flow, que j'utilise dans les fenêtres de maintenance.
Timeouts de pare-feu, NAT et Cloud-Idle
De nombreux pare-feux et passerelles NAT coupent les flux inactifs après 300-900 secondes, c'est pourquoi je Keepalive de manière à ce que mon intervalle soit inférieur. Sinon, l'application ne reconnaît l'interruption qu'à la prochaine requête et provoque des retours inutiles. Dans les cloud load balancers, je contrôle les paramètres TCP ou Connection Idle et les compare aux valeurs sysctl et proxy. Dans les configurations anycast ou multi-AZ, je vérifie si les changements de chemin conduisent à des sites homologues apparemment morts et j'augmente de manière ciblée le nombre d'échantillons pour ces zones. Je documente la chaîne client, proxy, pare-feu et backend afin de pouvoir Causes pour les drops.
Intégration dans la configuration du serveur web
Apache, Nginx et HAProxy organisent la persistance HTTP au niveau de l'application, tandis que le système d'exploitation TCP Keepalive livre. Dans Apache, j'active KeepAlive, je limite les KeepAliveRequests et je maintiens le KeepAliveTimeout à un niveau bas afin de libérer rapidement les workers. Dans Nginx, je mise sur une réutilisation efficace avec un keepalive_timeout court et un keepalive_requests modéré. Dans HAProxy, j'utilise des options de socket comme tcpka ou des valeurs par défaut côté système pour que les délais de transport correspondent à la politique du proxy. Pour les aspects plus profonds du serveur web, le Guide de réglage du serveur web, que je combine avec mes adaptations TCP.
Monitoring, tests et métriques
Je mesure l'effet de chaque ajustement et ne me fie pas aux Sens du ventre. ss, netstat et lsof me montrent combien de connexions ESTABLISHED, FIN_WAIT et TIME_WAIT sont présentes et si des fuites se développent. Dans les métriques, j'observe les abandons, les RST, les retransmissions, les P95/P99 de latence et les longueurs de file d'attente ; si une valeur atteint ses limites, je vais de manière ciblée à Idle, Intervall ou Probes. Avec des tests de charge synthétiques (par ex. ab, wrk, Locust), je simule des modèles d'utilisation réels et vérifie si le tuning atteint les métriques cibles. Je déploie les modifications par étapes et je compare les séries temporelles avant d'appliquer les modifications. global Répartir les valeurs par défaut sur tous les hôtes.
Problèmes courants et dépannage
Si je place des intervalles trop courts, je gonfle le Trafic de réseau et augmente le risque que des perturbations temporaires soient considérées comme des pannes. Si les sondes sont trop peu nombreuses, je ferme les connexions vivantes sur les réseaux lents, ce que les utilisateurs rencontrent sous la forme d'un message d'erreur sporadique. En revanche, des temps d'inactivité trop longs entraînent un engorgement des sockets et une augmentation des backlogs d'acceptation. Je vérifie les logs pour RST from client/server, ECONNRESET et ETIMEDOUT afin d'identifier la direction. Si les utilisateurs mobiles sont les plus touchés, j'adapte les sondes et les intervalles, parce que Trous de radio et les états de sommeil sont plus fréquents.
Des valeurs par défaut sûres pour différentes charges de travail
Je commence avec des valeurs conservatrices mais adaptées à la production et je les affine après avoir mesuré les Charge de travail. Les API Web ont généralement besoin de temps d'arrêt courts, les bases de données de temps nettement plus longs. Les proxies entre zones ou fournisseurs bénéficient d'un peu plus de sondes pour supporter le flottement des chemins. Pour les applications interactives, je réduis l'intervalle et augmente le nombre de sondes afin de remarquer plus rapidement les erreurs, mais de ne pas les fermer trop vite. Le tableau me donne une orientation compacte que j'adapte en cours d'utilisation.
| Type de serveur | Idle | Intervalle | échantillons | Remarque |
|---|---|---|---|---|
| Front-end d'hébergement web | 300-600s | 30-45s | 4-6 | Des sessions courtes, un volume élevé |
| Passerelle API | 180-300s | 20-30s | 5-6 | De nombreuses phases d'inactivité, un nettoyage rapide |
| Proxy de la base de données | 900-1800s | 45-60s | 3-5 | L'établissement de la connexion coûte cher, faire preuve de patience |
| Pod Kubernetes | 600-900s | 30-45s | 4–5 | Comparer avec les timeouts CNI/LB |
TCP_USER_TIMEOUT et backoff de retransmission
En plus de Keepalive, j'utilise de manière ciblée pour les connexions de données TCP_USER_TIMEOUT, Le paramètre "Durée de la connexion" permet de contrôler la durée pendant laquelle les données non confirmées peuvent rester dans le socket avant que la connexion ne soit activement interrompue. Cela est particulièrement important pour les proxies et les API qui ne doivent pas traîner les accrocs pendant des minutes. Contrairement à Keepalive (qui vérifie la viabilité en cas d'inactivité), TCP_USER_TIMEOUT intervient lorsque les données circulent mais qu'aucun ACK n'est renvoyé - par exemple en cas d'interférences asymétriques. Je le définis per-socket légèrement en dessous des timeouts de lecture/écriture de l'application, afin que le niveau de transport n'attende pas plus longtemps que la logique de l'application en cas d'erreur.
# Exemple (Go, Linux) - Keepalive et TCP_USER_TIMEOUT
d := net.Dialer{
Timeout : 5 * time.Second,
KeepAlive : 30 * time.Second,
Control : func(network, address string, c syscall.RawConn) error {
var err error
c.Control(func(fd uintptr) {
// 20s de données non confirmées sont autorisées
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 0x12, 20000) // TCP_USER_TIMEOUT
})
return err
},
}
conn, _ := d.Dial("tcp", "exemple:443")
Je n'oublie pas que le backoff TCP (prolongation du RTO) et les tentatives de relance (tcp_retries2) influencent également le comportement en cas de perte de paquets. Des délais d'attente utilisateur trop courts peuvent entraîner des interruptions dans des réseaux difficiles, bien que le poste correspondant soit accessible. C'est pourquoi je ne les place de manière étroite que là où je souhaite délibérément une détection rapide des erreurs (par exemple dans le proxy Edge).
IPv6 et particularités du système d'exploitation
Pour IPv6, les mêmes options per-socket s'appliquent (TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT). Selon la version du noyau, les valeurs par défaut globales pour v4 et v6 s'appliquent ensemble ; je vérifie cela avec ss -o à des connexions réelles. Sous Windows, j'adapte les valeurs par défaut via le registre (KeepAliveTime, KeepAliveInterval) et j'utilise SIO_KEEPALIVE_VALS pour les sockets individuels. Sur les dérivés BSD, les options ont parfois un autre nom, mais la sémantique reste la même. Il est important de vérifier pour chaque plateforme si les overrides des applications battent effectivement les defaults du système et si les runtimes des conteneurs héritent correctement des namespaces.
WebSockets, gRPC et streaming
Les flux à longue durée de vie (WebSocket, gRPC, Server-Sent Events) profitent particulièrement de keepalives bien dosés. J'interviens à deux niveaux : L'application envoie des pings/PONG périodiques (par ex. niveau WebSocket), tandis que la couche TCP sécurise avec des intervalles modérés. J'évite ainsi que les NAT suppriment les flux en silence. Pour les clients mobiles, j'augmente le nombre de sondes et je choisis des intervalles plus longs pour tenir compte des modes d'économie d'énergie. Pour gRPC/HTTP-2, je coordonne les PING HTTP/2 avec TCP Keepalive, afin d'éviter de faire deux fois des tests trop agressifs et de charger les batteries.
Conntrack, tables du noyau et du NAT
Dans les hôtes Linux où le suivi des connexions est actif, une connexion trop courte peut être nf_conntrack-peut conduire à un drop prématuré, même si l'application réfléchit plus longtemps. C'est pourquoi j'égalise les temporisateurs pertinents (par ex. nf_conntrack_tcp_timeout_established) avec mes intervalles de keepalive, afin qu'un échantillon arrive à coup sûr avant l'expiration du délai de conntrack. Sur les nœuds avec un NAT fort (NodePort, egress NAT), je planifie la taille de la table Conntrack et les buckets de hachage pour ne pas créer de pression globale sous la charge. Des paramètres keepalive propres allègent ces tables de manière mesurable.
Exemple : unités de proxy et de serveur web
Dans HAProxy, j'active de manière ciblée Keepalive côté transport et je maintiens la cohérence des timeouts HTTP :
# Extrait (HAProxy)
defaults
timeout client 60s
timeout serveur 60s
timeout connect 5s
option http-keep-alive
option tcpka # Activer TCP Keepalive (utiliser les valeurs par défaut du système d'exploitation)
backend app
serveur s1 10.0.0.10:8080 check inter 2s fall 3 rise 2
Dans Nginx, je considère que la réutilisation est efficace sans lier les travailleurs :
# Extrait (Nginx)
keepalive_timeout 30s ;
keepalive_requests 1000 ;
proxy_read_timeout 60s ;
proxy_send_timeout 60s ;
Je veille à ce que les délais de transport et d'application soient logiquement compatibles : Empêcher les „lignes mortes“ est la tâche de TCP/Keepalive, tandis que les délais d'application reflètent la logique commerciale et les attentes des utilisateurs.
L'observabilité dans la pratique
Je vérifie l'action de Keepalive en direct sur l'hôte :
- ss:
ss -tin 'sport = :443'montre avec-oles minuteries (par exemple. timer :(keepalive,30sec,0)), le nombre de retries et Send-/Recv-Q. - tcpdumpJe filtre une connexion en sommeil et je vois de petits paquets/ACKs périodiques pendant les phases d'inactivité. Cela me permet de savoir si les sondes déclenchent le NAT à temps.
- Logs/MétriquesJe corrige les pics de RST/timeout avec des modifications de Idle/Intervall/Probes. Une baisse du nombre de sockets ouverts à charge constante indique un nettoyage réussi.
Pour des tests reproductibles, je simule des interruptions de connexion (par ex. Interface down, iptables DROP) et j'observe la rapidité avec laquelle les travailleurs/processus libèrent des ressources et si les retries sont propres.
Planification des ressources et des capacités
Keepalive n'est qu'une partie de l'équilibre. Je m'assure que ulimit/nofile, fs.file-max, net.core.somaxconn et tcp_max_syn_backlog correspondent à mon nombre de connexions. Des temps d'inactivité trop longs masquent les déficits, tandis que des valeurs trop courtes apportent une prétendue stabilité, mais touchent durement les utilisateurs. Je planifie les tampons (Recv-/Send-Q) et les réserves FD avec des scénarios de charge et je mesure combien de connexions simultanées en mode veille mes nœuds peuvent réellement supporter avant que les GC/Worker et les files d'attente d'acceptation ne souffrent.
Quand je ne mise pas (uniquement) sur TCP Keepalive
Dans le cas d'un trafic purement interne sans NAT, d'un faible nombre de connexions et de timeouts d'application clairs, je renonce parfois à des keepalives agressifs et laisse la détection à l'application (par ex. heartbeats au niveau du protocole). Inversement, dans des scénarios Edge et mobiles, je donne la priorité à des intervalles courts, à un petit nombre de probes et je complète avec des pings HTTP/2 ou des pings WebSocket. Il est important que je ne tune jamais de manière isolée : Les valeurs keepalive doivent être en harmonie avec les retries, les circuits breakers et les stratégies de backoff, afin que je puisse identifier rapidement les erreurs, sans pour autant faire vaciller le système.
Stratégie de déploiement et validation
Je déploie les nouveaux paramètres par défaut par étapes : D'abord les hôtes Canary, ensuite une AZ/zone, puis l'ensemble de la flotte. Les comparaisons avant/après incluent les connexions ouvertes, le CPU en mode noyau, la latence P95/P99, les taux d'erreur et les retransmissions. Dans Kubernetes, je teste via des annotations de pod ou des conteneurs d'initialisation qui définissent des espaces de noms sysctl avant de procéder à des changements à l'échelle du nœud. Je minimise ainsi les risques et garantis des résultats reproductibles - pas seulement des améliorations perçues.
En bref
Avec des TCP Keepalive, je supprime rapidement les connexions inactives, je réduis la pression sur les ressources et je stabilise les temps de réponse. Je choisis des temps d'inactivité courts pour le front-end, des valeurs plus longues pour les backends stateful et je me protège avec des intervalles modérés et des sondes peu ou moyennement nombreuses. Je coordonne les valeurs avec les délais HTTP, TLS et proxy et je les maintiens en dessous des limites de ralenti du pare-feu et du NAT. Après chaque ajustement, je mesure les effets perceptibles sur la latence, les erreurs et le CPU au lieu de me fier à mon instinct. J'obtiens ainsi une fiable Plateforme qui gère mieux les pics de charge et qui sert les flux d'utilisateurs de manière uniforme.


