为什么我的 Web 服务器在高负载下会通过 TCP 重置断开连接?

为什么我的 Web 服务器在高负载下会通过 TCP 重置断开连接?

我有一个使用 nginx 的小型 VPS 设置。我想尽可能地提高它的性能,所以我一直在尝试优化和负载测试。

我正在使用 Blitz.io 通过获取一个小型静态文本文件来进行负载测试,并遇到一个奇怪的问题,即一旦同时连接的数量达到大约 2000 个,服务器似乎就会发送 TCP 重置。我知道这是一个非常大的数量,但是通过使用 htop,服务器仍然有足够的 CPU 时间和内存,所以我想找出这个问题的根源,看看我是否可以进一步推动它。

我在 2GB Linode VPS 上运行 Ubuntu 14.04 LTS(64 位)。

我的声誉不足以直接发布该图表,因此这里是 Blitz.io 图表的链接:

在此处输入图片描述

为了尝试找出问题的根源,我做了以下事情:

  • nginx 配置值worker_rlimit_nofile设置为 8192
  • 已将用户(nginx 的运行对象)nofile的硬限制和软限制都设置为 64000rootwww-data/etc/security/limits.conf
  • 没有迹象表明出现了任何问题/var/log/nginx.d/error.log(通常,如果您遇到文件描述符限制,nginx 将打印错误消息说明)

  • 我设置了 ufw,但没有速率限制规则。ufw 日志显示没有阻止任何内容,我尝试禁用 ufw,结果相同。

  • 不存在指示性错误/var/log/kern.log
  • 不存在指示性错误/var/log/syslog
  • 我添加了以下值/etc/sysctl.conf并加载它们,但sysctl -p没有效果:

    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 2000
    

有任何想法吗?

编辑:我做了一个新的测试,在一个非常小的文件(只有 3 个字节)上增加到 3000 个连接。这是 Blitz.io 图表:

Blitz.io 图表

再次,根据 Blitz 的说法,所有这些错误都是“TCP 连接重置”错误。

这是 Linode 带宽图。请记住,这是 5 分钟的平均值,因此它经过了一点低通滤波(瞬时带宽可能要高得多),但这仍然不算什么:

在此处输入图片描述

中央处理器:

在此处输入图片描述

输入/输出:

在此处输入图片描述

htop测试即将结束, 如下所示:顶部

我还在另一个(但看起来类似的)测试中使用 tcpdump 捕获了一些流量,并在出现错误时开始捕获: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

如果有人想看一下,这是文件(约 20MB):https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

这是来自 Wireshark 的带宽图:

在此处输入图片描述 (线代表所有数据包,蓝条代表 TCP 错误)

根据我对捕获的解释(我不是专家),TCP RST 标志似乎来自负载测试源,而不是服务器。因此,假设负载测试服务端没有问题,是否可以安全地假设这是负载测试服务和我的服务器之间某种网络管理或 DDOS 缓解的结果?

谢谢!

答案1

要设置打开文件的最大数量(如果这是导致问题的原因),您需要将“fs.file-max = 64000”添加到 /etc/sysctl.conf

答案2

连接重置的源头可能有很多。负载测试器可能没有可用的临时端口来启动连接,沿途的设备(例如执行 NAT 的防火墙)的 NAT 池可能已耗尽,无法为连接提供源端口,您这边是否有可能已达到连接限制的负载平衡器或防火墙?如果对入站流量执行源 NAT,也可能会遇到端口耗尽的情况。

确实需要两端的 pcap 文件。您要查找的是,如果发送了连接尝试但从未到达服务器,但仍显示为已被服务器重置。如果是这种情况,则必须重置连接。NAT 池耗尽是此类问题的常见原因。

此外,netstat -st 可能会为您提供一些额外的信息。

答案3

根据我最近类似的调优经历,可以尝试以下一些想法。参考:

您说这是一个静态文本文件。万一有任何上游处理正在进行,显然域套接字可以提高基于 TC 端口的连接的 TCP 吞吐量:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

无论上游如何终止:

启用 multi_accept 和 tcp_nodelay: http://tweaked.io/guide/nginx/

禁用 TCP 慢启动: https://stackoverflow.com/questions/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

优化TCP拥塞窗口(initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html

答案4

TIME_WAIT请使用命令查看有多少个端口处于状态netstat -patunl| grep TIME | wc -l并将其更改net.ipv4.tcp_tw_reuse为 1。

相关内容