Diagnose von Paketverlust / hoher Latenz in Ubuntu

7

Wir haben eine Linux-Box (Ubuntu 12.04) mit Nginx (1.5.2), die für einige Tornado- und Apache-Hosts als Reverse-Proxy / Load-Balancer fungiert. Die Upstream-Server sind physisch und logisch geschlossen (gleicher DC, manchmal gleiches Rack) und weisen eine Latenz von weniger als einer Millisekunde auf:

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

Wir erhalten eine anhaltende Last von ungefähr 500 Anfragen pro Sekunde und sehen derzeit regelmäßige Paketverlust- / Latenzspitzen aus dem Internet, selbst von einfachen Pings:

sam@AM-KEEN ~> ping -c 1000 loadbalancer
PING 50.xx.xx.16 (50.xx.xx.16): 56 data bytes
64 bytes from loadbalancer: icmp_seq=0 ttl=56 time=11.624 ms
64 bytes from loadbalancer: icmp_seq=1 ttl=56 time=10.494 ms

... many packets later ...

Request timeout for icmp_seq 2
64 bytes from loadbalancer: icmp_seq=2 ttl=56 time=1536.516 ms
64 bytes from loadbalancer: icmp_seq=3 ttl=56 time=536.907 ms
64 bytes from loadbalancer: icmp_seq=4 ttl=56 time=9.389 ms

... many packets later ...

Request timeout for icmp_seq 919
64 bytes from loadbalancer: icmp_seq=918 ttl=56 time=2932.571 ms
64 bytes from loadbalancer: icmp_seq=919 ttl=56 time=1932.174 ms
64 bytes from loadbalancer: icmp_seq=920 ttl=56 time=932.018 ms
64 bytes from loadbalancer: icmp_seq=921 ttl=56 time=6.157 ms

--- 50.xx.xx.16 ping statistics ---
1000 packets transmitted, 997 packets received, 0.3% packet loss
round-trip min/avg/max/stddev = 5.119/52.712/2932.571/224.629 ms

Das Muster ist immer das gleiche: Die Dinge funktionieren eine Weile gut (<20 ms), dann fällt ein Ping vollständig ab, dann drei oder vier Pings mit hoher Latenz (> 1000 ms), dann beruhigt es sich wieder.

Der Datenverkehr erfolgt über eine verbundene öffentliche Schnittstelle (wir werden sie nennen bond0), die als solche konfiguriert ist:

 bond0     Link encap:Ethernet  HWaddr 00:xx:xx:xx:xx:5d
           inet addr:50.xx.xx.16  Bcast:50.xx.xx.31  Mask:255.255.255.224
           inet6 addr: <ipv6 address> Scope:Global
           inet6 addr: <ipv6 address> Scope:Link
           UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
           RX packets:527181270 errors:1 dropped:4 overruns:0 frame:1
           TX packets:413335045 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:0 
           RX bytes:240016223540 (240.0 GB)  TX bytes:104301759647 (104.3 GB)

Anfragen werden dann über HTTP an Upstream-Server im privaten Netzwerk (wir können es nennen bond1) gesendet , das wie folgt konfiguriert ist:

  bond1     Link encap:Ethernet  HWaddr 00:xx:xx:xx:xx:5c  
            inet addr:10.xx.xx.70  Bcast:10.xx.xx.127  Mask:255.255.255.192
            inet6 addr: <ipv6 address> Scope:Link
            UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
            RX packets:430293342 errors:1 dropped:2 overruns:0 frame:1
            TX packets:466983986 errors:0 dropped:0 overruns:0 carrier:0
            collisions:0 txqueuelen:0 
            RX bytes:77714410892 (77.7 GB)  TX bytes:227349392334 (227.3 GB)

Ausgabe von uname -a:

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

Wir haben angepasst sysctl.conf, um das Problem zu beheben, ohne Erfolg. Ausgabe von /etc/sysctl.conf(ohne irrelevante Konfigurationen):

# net: core
net.core.netdev_max_backlog = 10000

# net: ipv4 stack
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

Ausgabe von dmesg -dmit unterdrückten Nicht-ICMP-UFW-Nachrichten:

[508315.349295 <   19.852453>] [UFW BLOCK] IN=bond1 OUT= MAC=<mac addresses> 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)

Wie kann ich die Ursache dieses Problems auf einer Linux-Box der Debian-Familie diagnostizieren?

Sgammon
quelle
Ein weiterer interessanter Hinweis: Verlust und hohe Latenz scheinen mit E / A-Schreibvorgängen zu korrelieren. Das Deaktivieren von Protokollen verbessert die Situation, das Problem tritt jedoch weiterhin regelmäßig auf.
Sgammon
Können Sie eine dmesg-Ausgabe bereitstellen, wenn auf der TCP / IP-Seite keine Probleme auftreten, die Probleme verursachen würden?
Tabiko
Dmesg-Ausgabe hinzugefügt. Ich habe die einzigen zwei Zeilen eingefügt, die anomal zu sein scheinen - es gibt viel mehr UFW BLOCK-Nachrichten - können Beispiele von diesen posten, wenn Sie glauben, dass sie verwandt sein könnten
sgammon

Antworten:

8

Wenn ein Teil Ihres Netzwerks auf dem Weg gesättigt ist oder wenn eine Verbindung innerhalb des Netzwerks Fehler auslöst, kann es zu Paketverlusten kommen. Dies wird in den Schnittstellenfehlern nicht angezeigt, es sei denn, Sie haben das Problem direkt bei der Kabelverbindung zwischen Switch und Server. Wenn das Problem irgendwo anders im Netzwerk liegt, wird es als verlorene Pakete angezeigt.

Sie können dieses Problem auftreten, wenn Sie TCP-Verkehr haben, da es im Kernel Zähler gibt, die TCP verfolgen und Wiederherstellungsschritte ausführen, um verlorene Pakete im Stream zu berücksichtigen. Schauen Sie sich die -sOption (Statistiken) an netstat. Die dargestellten Werte sind Zähler, daher müssen Sie sie eine Weile beobachten, um ein Gefühl dafür zu bekommen, was normal und was anomal ist, aber die Daten sind vorhanden. Die retransmitund data lossZähler sind besonders nützlich.

[sadadmin@busted ~]$ netstat -s | egrep -i 'loss|retran'
2058 segments retransmited
526 times recovered from packet loss due to SACK data
193 TCP data loss events
TCPLostRetransmit: 7
2 timeouts after reno fast retransmit
1 timeouts in loss state
731 fast retransmits
18 forward retransmits
97 retransmits in slow start
4 sack retransmits failed

Einige Tools testen diese Werte und geben sie für Sie an, sodass Sie leicht erkennen können, wenn etwas nicht stimmt. Ich benutze Munin .

Joshua Miller
quelle
Vielen Dank für Ihre Antwort, ich werde sehen, was ich finden kann. Würde das Kernel-Konfigurationselement verhindern, net.ipv4.tcp_no_metrics_save = 1dass Statistiken aufgezeichnet werden?
Sgammon