![Varnish 开放端口耗尽,有大量 SYN_SENT 连接](https://linux22.com/image/797891/Varnish%20%E5%BC%80%E6%94%BE%E7%AB%AF%E5%8F%A3%E8%80%97%E5%B0%BD%EF%BC%8C%E6%9C%89%E5%A4%A7%E9%87%8F%20SYN_SENT%20%E8%BF%9E%E6%8E%A5.png)
最近,我们的 Varnish (3x) -> Apache (3x) 设置出现了问题,导致SYN_SENT
连接数急剧增加。
峰值本身是由于大量新流量访问网站(而不是任何类型的 DDOS),而且似乎我们的 Varnish 机器在将流量转发到后端服务器时遇到了问题(Apache 流量的下降与 Varnish 上的峰值相关),从而导致可用端口池拥塞SYN_SENT
。
Apache 上启用了保持活动 (15 秒)。
故障出在哪一边?流量很大,但无论如何都不会导致这样的设置(3 台 Varnish 前端机器,3 台后端 Apache 服务器)停滞。
请帮忙。
Munin 通过防火墙的连接的屏幕截图这里。
漆
~$ netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c
9 CLOSE_WAIT
12 CLOSING
718 ESTABLISHED
39 FIN_WAIT1
1714 FIN_WAIT2
76 LAST_ACK
12 LISTEN
256 SYN_RECV
6124 TIME_WAIT
/etc/sysctl.conf(Varnish)
net.ipv4.netfilter.ip_conntrack_max = 262144
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 60
net.ipv4.ip_local_port_range = 1024 65536
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_fin_timeout = 30
阿帕奇
netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c
11 CLOSE_WAIT
286 ESTABLISHED
38 FIN_WAIT2
14 LISTEN
7220 TIME_WAIT
/etc/sysctl.conf(Apache)
vm.swappiness=10
net.core.wmem_max = 524288
net.core.wmem_default = 262144
net.core.rmem_default = 262144
net.core.rmem_max = 524288
net.ipv4.tcp_rmem = 4096 262144 524288
net.ipv4.tcp_wmem = 4096 262144 524288
net.ipv4.tcp_mem = 4096 262144 524288
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_keepalive_time = 30
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.core.somaxconn = 2048
net.ipv4.conf.lo.arp_ignore=8
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
vm.swappiness = 0
kernel.sysrq=1
kernel.panic = 30
答案1
您的问题可能出在 Apache 服务器上的 sysctl 上。
一些假设:通常 Varnish 处理每个连接的速度比 Web 服务器快得多(除非您的 Varnish 服务器的 CPU 少得多,并且您的 Apache 服务器仅提供缓存在内存中的静态文件。)我假设您的连接在 Varnish 中处理的速度比在 Apache 中更快。
因此,您的 Apache 服务器上的资源可能充足,但请求必须在某处排队,即使时间很短。目前,它们并没有以健康的方式排队,最终无法得到处理。
看起来您的请求被困在 Varnish 中,而无法到达 Apache 服务器。
有一些证据可以证明这一点:
请注意,在您的 munin 图中,在 SYN_SENT 备份之前,TIME_WAIT 中的请求会增加,然后在某个点之后,它们开始堆积为 SYN_SENTS。这表明请求开始得到更慢的响应,然后队列备份并且请求根本没有得到响应。
这表明您的 Apache 服务器没有接受足够的连接(它们可以坐在那里排队等待 Apache 来处理它们。)
我在您的配置文件中看到了几个可能的限制:
当出现峰值时,您的 Varnish 服务器上大约有 30000 个处于 SYN_SENT 状态的连接。
然而,在 Apache 服务器上,您的 max_syn_backlog 只有 16384。您的 somaxconn 只有 2048。
还要注意,Apache 服务器上的网络内存缓冲区大小非常低。您已在 Varnish 服务器上将其调整为 16MB。但在 Apache 服务器上,您的 net.ipv4.tcp_rmem 只有 524KB,以匹配您的 net.core.rmem_max。
我建议在 Apache 服务器上提高所有这些参数。
您将需要更多地关注 Apache 服务器上的诊断以准确了解正在发生的事情,但如果您提高这些值,则可能不需要这样做。
您可能不应该调整 net.ipv4.tcp_mem。请注意,此参数的单位是页,而不是字节,因此从 net.ipv4.tcp_rmem 或 net.ipv4.tcp_wmem(均以字节为单位)复制相同的值没有任何意义。它由 Linux 根据您的内存量自动调整,因此很少需要调整。事实上,这可能是您的问题,任意限制可用于整体连接排队的内存。
看: http://russ.garrett.co.uk/2009/01/01/linux-kernel-tuning/
还要注意,“vm.swappiness = 0”被设置了两次,一次设置为 10,另一次在底部设置为 0,这是有效值。
答案2
在 Varnish 服务器上,尝试更改这 2 个参数:
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
tw_reuse 将允许它重用 TIME_WAIT 中的连接。
tw_recycle 可能会导致负载平衡器等出现问题。