我在 EC2 中运行了 7 台 Ubuntu 14.04.4 服务器。其中一台服务器托管 memcached(端口 11211),另外 6 台是客户端。 在 6 个客户端中,5 个能够连接,1 个无法连接(参见注释)。
我对连接的两端进行了 TCP 转储。我看到客户端发送了一个 SYN 请求,但没有返回 ACK。失败连接的 tcpdump 如下所示(此后 SYN 重复多次)
1 0.000000 172.16.1.58 172.16.1.94 TCP 76 43469 → 11211 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=849737 TSecr=0 WS=128
对于来自不同服务器的成功连接:
1 0.000000 172.16.1.64 172.16.1.94 TCP 76 44908 → 11211 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=19201098 TSecr=0 WS=128
2 0.000298 172.16.1.64 172.16.1.94 TCP 68 44908 → 11211 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=19201098 TSecr=3160738522
更多跟踪和命令:
working-client$ nc -vnz 172.16.1.94 11211
Connection to 172.16.1.94 11211 port [tcp/*] succeeded!
broken-client$ nc -vnz 172.16.1.94 11211
nc: connect to 172.16.1.94 port 11211 (tcp) failed: Connection timed out
broken-client$ nc -vnz -q 5 -u 172.16.1.94 11211
Connection to 172.16.1.94 11211 port [udp/*] succeeded!
路由表(所有客户端和服务器上均相同)
$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default ip-172-16-1-1.e 0.0.0.0 UG 0 0 0 eth0
172.16.1.0 * 255.255.255.0 U 0 0 0 eth0
损坏的客户端上的 IP 表
broken-client$ sudo iptables -nvL -t nat
--------------------------------------
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
broken-client$ sudo iptables -nvL
--------------------------------------
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
服务器上的 IP 表
server$ sudo iptables -nvL -t nat
--------------------------------------
Chain PREROUTING (policy ACCEPT 7332 packets, 531K bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 7332 packets, 531K bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 370 packets, 25781 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 370 packets, 25781 bytes)
pkts bytes target prot opt in out source destination
server$ sudo iptables -nvL
--------------------------------------
Chain INPUT (policy ACCEPT 1963K packets, 341M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 2670K packets, 5518M bytes)
pkts bytes target prot opt in out source destination
所有客户端均从同一基础映像克隆而来,应完全相同。我们不使用 iptables,所有服务器都位于同一子网和安全组中。
问题不在于 memcached:我可以使用 telnet(端口 22 或端口 11211)或 ssh 重现该问题,虽然安全组允许它们连接,但两者都不允许连接。
Ping 已禁用,但只要不是这两个服务器,我就可以在服务器之间跟踪路由(缓存 <=> 客户端,客户端 <=> 缓存)。
看起来(参见上面的跟踪)可以建立 UDP 连接,但不能建立 TCP 连接。
这个问题一直存在。
注意:6 个客户端服务器是自动扩展组(在 VPC 中)的一部分。根据负载,服务器数量在 1 到 6 之间,有时一台服务器无法连接。IP 地址和服务器名称确实会被重复使用。
我该看什么来找到连接失败的地方?
答案1
这似乎是由新 Linux 内核中的 ARP 缓存(MAC 地址缓存)引起的。
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1331150