我正在尝试尽其所能地扩展 nginx 安装。
我正在运行一个 nginx 实例,其中有 6 个 worker_processes(6 个核心)和 5 个后端服务器,uwsgi
每个服务器由 10 个 worker 组成(总共 50 个 worker)。
但是,我尝试使用不同的参数(使用ab
)对总连接数和并发连接数进行的任何基准测试似乎都达到每秒 1000 个请求左右。
我已禁用 nginx 和 uwsgi 的所有日志记录(以避免因磁盘问题而导致速度变慢)。我正在针对仅发送{'status':'ok'}
回的 Flask python 应用程序进行测试。没有数据库访问,没有计算,什么都没有。
nginx 配置的相关部分如下所示:
user www-data;
worker_processes 6;
worker_rlimit_nofile 100000;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 2048;
multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log off; # /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
<...>
}
我正在寻找任何技巧,任何我忽略的技巧,以提高吞吐量。查看每个uwsgi
池的统计数据(使用uwsgitop
),它们在任何时候似乎都没有难以执行,这让我相信 nginx 是瓶颈。此外,单个工作池的性能与 10 个工作池相同。此外htop
还显示我在内存或 CPU 方面远未达到最大值。
答案1
我建议您安装sysstat
包然后使用以下方法检查记录的信息特区。
sar -n SOCK -s <start_time> -e <end_time>
获取基准测试期间的套接字数量
sar -n DEV -s <start_time> -e <end_time>
获取网络接口数据包和带宽
sar -d -s <start_time> -e <end_time>
获取每个设备的 io 统计信息
sar -v -s <start_time> -e <end_time>
获取文件句柄和 inode 的数量
ETC
检查用户的安全限制(最大打开文件数、最大进程数等)。
然后检查内核设置:本地端口范围、somaxconn、设备 txqueue、netdev backlog,如果需要则激活 TIME_WAIT 状态的套接字回收(关于带有 sar -n SOCK 的 tcp-tw)使用 nginx 中的 SO_LINGER 或 tcp_tw_recycle(如果您没有 NAT)或重用(用于传出连接),如果需要则更改 tw_buckets 的数量,确保 sack/dsack 和时间戳已启用,减少 FIN_WAIT_2 超时,如果需要则增加最大文件句柄数等。
可能有很多因素。
在检查所有这些之前,请确保您不在ab
同一台设备上运行并且该 Python 应用程序具有良好的响应时间。
进行一个简单的测试以确保 python 应用程序不是罪魁祸首:通过 nginx 直接在静态文件服务器上进行相同的基准测试。
答案2
除了这里的另外两个答案之外,conntrack(连接跟踪)也可能是一个问题。如果您使用的是 Linux 并且使用的是 netfilter(即 iptables),那么您的 conntrack 表可能已满。
首先检查 conntrack 是否已启用。例如:
$ /sbin/lsmod | grep conntrack
ip_conntrack 51617 1 xt_state
$ lsmod | grep -i con
nf_conntrack_ipv4 19159 5
nf_defrag_ipv4 12729 1 nf_conntrack_ipv4
nf_conntrack 92358 5 xt_state,iptable_nat,nf_conntrack_ipv4,nf_nat_ipv4,nf_nat
输出将根据内核版本的不同而变化。
如果加载了nf_conntrack
或ip_conntrack
模块,您可以查看有多少个 conntrack 条目,并使用以下命令检查最大值是多少:
Red Hat(RHEL、CentOS、Fedora 等):
$ sudo wc -l /proc/net/ip_conntrack
$ /sbin/sysctl -a | grep conntrack_max
or
$ sudo wc -l /proc/net/nf_conntrack
$ /sbin/sysctl -a | grep conntrack_max
Debian:
$ cat /proc/sys/net/netfilter/nf_conntrack_count
$ /sbin/sysctl -a | grep conntrack_max
如果您已经填充了 conntrack 表,那么您将需要通过或 /etc/sysctl.conf 增加限制sysctl
。
笔记:conntrack 不仅仅适用于服务器。您需要检查您自己和服务器之间的每个点:客户端计算机、负载平衡器 (nginx)、上游 (后端) 服务器,甚至可能是任何路由器。
答案3
我会查看文件描述符、可能的网络/接口饱和度以及 IO 问题。
要查看网络接口是否饱和,请使用 iptraf,这是一个用于查看实时统计数据的命令行工具。只需:
iptraf
对于 IO 问题,请使用 iostat
iostat 1
它将每秒显示一次 IO 使用情况和负载。
对于文件描述符问题,请使用 lsof 或 /proc:
lsof -P -n -p <PID> | wc -l
ls /proc/<PID>/fd | wc -l
使用该ulimit -a | grep files
命令(以运行该进程的用户身份)验证允许打开的文件数。默认值为 1024。
请参阅此页面了解更多信息: http://www.cyberciti.biz/tips/linux-procfs-file-descriptors.html
请参阅此问题以了解 nginx 特定的文件描述符问题,该问题可能与您的问题非常相关: 了解 Linux 和 nginx 的最大文件描述符以及 worker_rlimit_nofile 的最佳值