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 -d
mit 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?
Antworten:
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
-s
Option (Statistiken) annetstat
. 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. Dieretransmit
unddata loss
Zähler sind besonders nützlich.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 .
quelle
net.ipv4.tcp_no_metrics_save = 1
dass Statistiken aufgezeichnet werden?