Quand les paquets UDP disparaissent : détecter les pertes silencieuses sur sa propre machi

Un flux UDP perdait environ un tiers de ses datagrammes. Aucune alerte du commutateur, aucune erreur de carte réseau – juste des trous dans la numérotation. La première réaction est d’incriminer le réseau, pourtant ici le coupable était la machine elle-même. Les paquets arrivaient intacts, mais le tampon de socket de l’hôte débordait et les supprimait silencieusement avant que l’application ne puisse les lire. Distinguer les pertes côté hôte des échecs réseau est crucial, et cela commence par un simple compteur du noyau.
Suivre le chemin de réception
Sur Linux, le parcours d’un datagramme UDP est simple : carte réseau → tampon de réception du noyau → appel à recv(). Si votre code n’extrait pas assez vite les datagrammes, le tampon se remplit et le noyau élimine l’excédent. Le système comptabilise ces pertes sous le nom d’« erreurs de tampon de réception », visibles avec netstat -su ou /proc/net/snmp. Quand RcvbufErrors augmente, le réseau a fait son travail ; c’est l’hôte qui n’a pas suivi. Un simple coup d’œil à ce compteur peut remplacer des jours d’incertitude du type « est-ce le commutateur ? ».
Le comportement en rafales prime sur le débit moyen
L’enquête a révélé que le tampon de 208 Ko par défaut était submergé par des rafales brèves de l’expéditeur. Bien que le débit moyen paraisse sain sur tous les tableaux de bord, des pics de quelques millisecondes remplissaient le tampon plus vite qu’un seul fil de réception ne pouvait l’extraire. La métrique pertinente n’était pas le débit moyen, mais le pic de rafale par rapport au taux d’extraction. Augmenter le tampon et déléguer le traitement a aidé, mais la vraie solution a commencé par une extraction plus rapide.
Solutions pratiques pour en finir avec les pertes silencieuses
Commencez par externaliser tout traitement lourd hors de la boucle de réception : copiez le datagramme dans une file d’attente et retournez immédiatement à recv(). Ensuite, agrandissez le tampon du socket avec setsockopt(SO_RCVBUF) et augmentez net.core.rmem_max pour que le noyau prenne en compte ce changement. Pour les flux à haut volume, regroupez les appels système avec recvmmsg() afin de réduire les frais par paquet. Si un cœur reste en retard, SO_REUSEPORT permet à plusieurs fils de partager le même port avec des tampons distincts. En général, il faut à la fois un tampon plus grand et une extraction plus rapide.
Source : DEV Community. Synthèse éditoriale assistée par IA — TechnoExpress.

