9 votes

Diagnostiquer la perte de paquets / la latence élevée dans Ubuntu

Nous avons une boîte Linux (Ubuntu 12.04) exécutant Nginx (1.5.2), qui agit en tant que proxy inverse/load balancer pour certains hôtes Tornado et Apache. Les serveurs amont sont physiquement et logiquement proches (même centre de données, parfois même rack) et présentent une latence inférieure à la milliseconde entre eux :

 PING appserver (10.xx.xx.112) 56(84) bytes of data.
 64 octets de appserver (10.xx.xx.112) : icmp_req=1 ttl=64 time=0.180 ms
 64 octets de appserver (10.xx.xx.112) : icmp_req=2 ttl=64 time=0.165 ms
 64 octets de appserver (10.xx.xx.112) : icmp_req=3 ttl=64 time=0.153 ms

Nous recevons une charge soutenue d'environ 500 requêtes par seconde, et constatons actuellement des pertes de paquets régulières / des pics de latence depuis Internet, même à partir de pings basiques :

sam@AM-KEEN ~> ping -c 1000 loadbalancer
PING 50.xx.xx.16 (50.xx.xx.16): 56 octets de données
64 octets de loadbalancer: icmp_seq=0 ttl=56 time=11.624 ms
64 octets de loadbalancer: icmp_seq=1 ttl=56 time=10.494 ms

... nombreux paquets plus tard ...

Délai de la demande pour icmp_seq 2
64 octets de loadbalancer: icmp_seq=2 ttl=56 time=1536.516 ms
64 octets de loadbalancer: icmp_seq=3 ttl=56 time=536.907 ms
64 octets de loadbalancer: icmp_seq=4 ttl=56 time=9.389 ms

... nombreux paquets plus tard ...

Délai de la demande pour icmp_seq 919
64 octets de loadbalancer: icmp_seq=918 ttl=56 time=2932.571 ms
64 octets de loadbalancer: icmp_seq=919 ttl=56 time=1932.174 ms
64 octets de loadbalancer: icmp_seq=920 ttl=56 time=932.018 ms
64 octets de loadbalancer: icmp_seq=921 ttl=56 time=6.157 ms

--- Statistiques du ping vers 50.xx.xx.16 ---
1000 paquets envoyés, 997 paquets reçus, 0.3% de perte
aller-retour min/moy/max/ecart = 5.119/52.712/2932.571/224.629 ms

Le schéma est toujours le même : les choses fonctionnent bien pendant un certain temps (<20ms), puis un ping disparaît complètement, suivies de trois ou quatre pings à haute latence (>1000ms), puis ça se stabilise à nouveau.

Le trafic arrive via une interface publique liée (nous l'appellerons bond0) configurée comme suit :

 bond0     Encapsulation de lien : Ethernet  Adresse matérielle 00:xx:xx:xx:xx:5d
           Adresse IP : 50.xx.xx.16  Diffusion : 50.xx.xx.31  Masque : 255.255.255.224
           Adresse IPv6 :  Portée : Global
           Adresse IPv6 :  Portée : Lien
           UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
           Paquets RX : 527181270 erreurs :1 abandonnés :4 dépassements:0 trames :1
           Paquets TX : 413335045 erreurs :0 abandonnés :0 dépassements:0 transporteur:0
           collisions:0 longueur file d'attente de transmission:0 
           Octets RX : 240016223540 (240,0 Go)  Octets TX : 104301759647 (104,3 Go)

Les requêtes sont ensuite soumises via HTTP aux serveurs amont sur le réseau privé (nous pouvons l'appeler bond1), qui est configuré comme suit :

  bond1     Encapsulation de lien : Ethernet  Adresse matérielle 00:xx:xx:xx:xx:5c  
            Adresse IP : 10.xx.xx.70  Diffusion : 10.xx.xx.127  Masque : 255.255.255.192
            Adresse IPv6 :  Portée : Lien
            UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
            Paquets RX : 430293342 erreurs :1 abandonnés :2 dépassements:0 trames :1
            Paquets TX : 466983986 erreurs :0 abandonnés :0 dépassements:0 transporteur:0
            collisions:0 longueur file d'attente de transmission:0 
            Octets RX : 77714410892 (77,7 Go)  Octets TX : 227349392334 (227,3 Go)

Sortie de uname -a :

Linux 3.5.0-42-generic #65~precise1-Ubuntu SMP Wed Oct 2 20:57:18 UTC 2013 x86_64 GNU/Linux

Nous avons personnalisé sysctl.conf dans le but de résoudre le problème, sans succès. Sortie de /etc/sysctl.conf (avec les configurations non pertinentes omises) :

# net: core
net.core.netdev_max_backlog = 10000

# pile ipv4 du réseau
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_max_syn_backlog = 10000
net.ipv4.tcp_congestion_control = cubic
net.ipv4.ip_local_port_range = 8000 65535

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2

net.ipv4.tcp_thin_dupack = 1
net.ipv4.tcp_thin_linear_timeouts = 1

net.netfilter.nf_conntrack_max = 99999999
net.netfilter.nf_conntrack_tcp_timeout_established = 300

Sortie de dmesg -d, avec les messages UFW non-ICMP supprimés :

[508315.349295 <   19.852453>] [UFW BLOCK] IN=bond1 OUT= MAC= SRC=118.xx.xx.143 DST=50.xx.xx.16 LEN=68 TOS=0x00 PREC=0x00 TTL=51 ID=43221 PROTO=ICMP TYPE=3 CODE=1 [SRC=50.xx.xx.16 DST=118.xx.xx.143 LEN=40 TOS=0x00 PREC=0x00 TTL=249 ID=10220 DF PROTO=TCP SPT=80 DPT=53817 WINDOW=8190 RES=0x00 ACK FIN URGP=0 ] 

[517787.732242 <    0.443127>] Peer 190.xx.xx.131:59705/80 unexpectedly shrunk window 1155488866:1155489425 (repaired)

Comment puis-je diagnostiquer la cause de ce problème sur une boîte Linux de la famille Debian ?

10voto

cellepo Points 113

Si une partie de votre réseau est saturée quelque part, ou si un lien dans le réseau génère des erreurs, vous pouvez connaître des pertes de paquets. Cela ne se reflètera pas dans le compteur d'erreurs de l'interface à moins que le problème se produise juste à la connexion du câble commutateur-serveur. Si le problème se situe ailleurs dans le réseau, il se manifeste par des paquets perdus.

Vous pouvez mettre en évidence ce problème si vous avez du trafic TCP, car il existe des compteurs dans le noyau qui suivent les étapes de récupération des paquets perdus dans le flux TCP. Jetez un œil à l'option -s (stats) sur netstat. Les valeurs présentées sont des compteurs, donc vous devrez les surveiller un moment pour vous faire une idée de ce qui est normal et de ce qui est anormal, mais les données sont là. Les compteurs de retransmission et de perte de données sont particulièrement utiles.

[sadadmin@busted ~]$ netstat -s | egrep -i 'loss|retran'
2058 segments retransmis
526 fois récupérés à cause de pertes de paquets dues à des données SACK
193 événements de perte de données TCP
TCPLostRetransmit : 7
2 délais après une retransmission rapide reno
1 délai à l'état de perte
731 retransmissions rapides
18 retransmissions avant
97 retransmissions en slow start
4 retransmissions SACK échouées

Certains outils échantillonneront ces valeurs et les suivront pour vous permettre de voir facilement quand quelque chose ne va pas. Personnellement, j'utilise munin.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X