![+200 个并发连接后 NGINX 超时](https://linux22.com/image/569632/%2B200%20%E4%B8%AA%E5%B9%B6%E5%8F%91%E8%BF%9E%E6%8E%A5%E5%90%8E%20NGINX%20%E8%B6%85%E6%97%B6.png)
这是我的nginx.conf
(我已经更新了配置以确保不涉及 PHP 或任何其他瓶颈):
user nginx;
worker_processes 4;
worker_rlimit_nofile 10240;
pid /var/run/nginx.pid;
events
{
worker_connections 1024;
}
http
{
include /etc/nginx/mime.types;
error_log /var/www/log/nginx_errors.log warn;
port_in_redirect off;
server_tokens off;
sendfile on;
gzip on;
client_max_body_size 200M;
map $scheme $php_https { default off; https on; }
index index.php;
client_body_timeout 60;
client_header_timeout 60;
keepalive_timeout 60 60;
send_timeout 60;
server
{
server_name dev.anuary.com;
root "/var/www/virtualhosts/dev.anuary.com";
}
}
我在用http://blitz.io/play测试我的服务器(我购买了 10 000 个并发连接计划)。在 30 秒的运行中,我获得了964
命中数和5,587 timeouts
。第一次超时发生在测试进行到 40.77 秒时,当时并发用户数为 200。
测试期间,服务器负载为(top
输出):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 20225 nginx 20 0 48140 6248 1672 S 16.0 0.0 0:21.68 nginx
1 root 20 0 19112 1444 1180 S 0.0 0.0 0:02.37 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.03 migration/0
所以不是服务器资源的问题,那到底是什么问题呢?
更新时间:2011 12 09 GMT 17:36。
到目前为止,我做了以下更改以确保瓶颈不是 TCP/IP。添加到/etc/sysctl.conf
:
# These ensure that TIME_WAIT ports either get reused or closed fast.
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_tw_recycle = 1
# TCP memory
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
更多调试信息:
[root@server node]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 126767
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
NB:这worker_rlimit_nofile
设置为10240
nginx 配置。
更新时间:2011 12 09 GMT 19:02。
看起来我做的更改越多,情况就越糟糕,但这里有新的配置文件。
user nginx;
worker_processes 4;
worker_rlimit_nofile 10240;
pid /var/run/nginx.pid;
events
{
worker_connections 2048;
#1,353 hits, 2,751 timeouts, 72 errors - Bummer. Try again?
#1,408 hits, 2,727 timeouts - Maybe you should increase the timeout?
}
http
{
include /etc/nginx/mime.types;
error_log /var/www/log/nginx_errors.log warn;
# http://blog.martinfjordvald.com/2011/04/optimizing-nginx-for-high-traffic-loads/
access_log off;
open_file_cache max=1000;
open_file_cache_valid 30s;
client_body_buffer_size 10M;
client_max_body_size 200M;
proxy_buffers 256 4k;
fastcgi_buffers 256 4k;
keepalive_timeout 15 15;
client_body_timeout 60;
client_header_timeout 60;
send_timeout 60;
port_in_redirect off;
server_tokens off;
sendfile on;
gzip on;
gzip_buffers 256 4k;
gzip_comp_level 5;
gzip_disable "msie6";
map $scheme $php_https { default off; https on; }
index index.php;
server
{
server_name ~^www\.(?P<domain>.+);
rewrite ^ $scheme://$domain$request_uri? permanent;
}
include /etc/nginx/conf.d/virtual.conf;
}
更新时间:2011 12 11 GMT 20:11。
这是netstat -ntla
测试期间的输出。
https://gist.github.com/d74750cceba4d08668ea
更新时间:2011 12 12 GMT 10:54。
需要澄清的是,iptables
测试时防火墙是关闭的。
更新时间:2011 12 12 GMT 22:47。
这里就是sysctl -p | grep mem
垃圾场。
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 8388608 8388608 8388608
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 65536 8388608
net.ipv4.route.flush = 1
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_max = 8388608
net.core.wmem_default = 65536
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
更新时间 2011 12 12 GMT 22:49
我用来blitz.io
运行所有测试。我测试的 URL 是http://dev.anuary.com/test.txt,使用以下命令:--region ireland --pattern 200-250:30 -T 1000 http://dev.anuary.com/test.txt
更新时间 2011 12 13 GMT 13:33
nginx
用户限制(在 中设置/etc/security/limits.conf
)。
nginx hard nofile 40000
nginx soft nofile 40000
答案1
您需要在测试期间转储网络连接。虽然服务器可能接近零负载,但您的 TCP/IP 堆栈可能会超负荷。在 netstat 输出中查找 TIME_WAIT 连接。
如果是这种情况,那么您将需要检查调整与 TCP 等待状态、TCP 回收和类似指标相关的 tcp/ip 内核参数。
此外,您还没有描述正在测试的内容。
我总是测试:
- 静态内容(图像或文本文件)
- 简单的 php 页面(例如 phpinfo)
- 申请页面
这可能不适用于你的情况,但我在性能测试时会这么做。测试不同类型的文件可以帮助你找出瓶颈。
即使是静态内容,测试不同大小的文件也很重要,以了解超时和其他指标。
我们有一些静态内容 Nginx 盒,可处理 3000 多个活动连接。因此 Nginx 肯定能做到。
更新:您的 netstat 显示有很多打开的连接。可能需要尝试调整您的 TCP/IP 堆栈。另外,您请求什么文件?Nginx 应该会快速关闭端口。
以下是针对 sysctl.conf 的建议:
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
这些值非常低,但我在高并发 Nginx 盒子上成功使用了它们。
答案2
另一个假设。您已经增加了worker_rlimit_nofile
,但最大客户端数量是在文档中定义作为
max_clients = worker_processes * worker_connections
如果您尝试增加到worker_connections
8192 会怎么样?或者,如果有足够的 CPU 核心,增加worker_processes
?
答案3
我遇到了一个非常类似的问题,nginx 盒作为 apache 服务器上游的负载平衡器。
就我而言,我能够将问题隔离为与网络相关的问题,因为上游 Apache 服务器变得过载。当整个系统处于负载状态时,我可以使用简单的 Bash 脚本重新创建它。根据其中一个挂起进程的 strace,connect 调用正在获取 ETIMEDOUT。
这些设置(在 nginx 和上游服务器上)为我消除了这个问题。在进行这些更改之前,我每分钟会遇到 1 或 2 次超时(每秒处理约 100 个请求),现在为 0。
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 4096
net.ipv4.tcp_max_tw_buckets = 400000
net.core.somaxconn = 4096
我不建议使用 net.ipv4.tcp_tw_recycle 或 net.ipv4.tcp_tw_reuse,但如果你想使用其中一个,就选择后者。如果存在任何延迟,它们可能会导致奇怪的问题,而后者至少是两者中更安全的。
我认为将 tcp_fin_timeout 设置为 1 也可能会造成一些麻烦。尝试将其设置为 20/30 - 仍然远低于默认值。
答案4
您的设置太低max open files
(1024),请尝试更改并重新启动 nginx。(cat /proc/<nginx>/limits
确认)
ulimit -n 10240
并增加到worker_connections
10240或更高。