[TOC]
Nginx 压测和性能分析的一些经验
Nginx 压测的一些经验
关注网卡带宽、网卡队列
- 单个千兆网卡的机器,去压测 nginx 的性能,会存在带宽的瓶颈,这个时候观察 CPU 和带宽,发现 CPU 没有跑满,si 也没有满,但是网卡带宽流量已经达到了瓶颈,对于千兆网卡这个说的小 b,而不是大 B;然后理论上千兆网卡的上限是 128MB/s,但是由于种种因素,一般很难达到 128,但是一般而言到了 110MB/s 以上就已经是瓶颈了。
-
千兆网卡基础上,网卡会存在瓶颈,在这个基础上Nginx 当做 Web Server 的话,针对 http:
- 0KB,QPS = 48w (return 200)
- 0KB,QPS = 29w (return 302)
- 1B, QPS = 23w
- 1KB,QPS = 9w
-
Nginx 直接 return 200 和 return 302,QPS 相差很多(千兆网卡基础上)
- 在千兆网卡上, return 200, QPS 48w;return 302, QPS 29w。原因是因为 return 302 的返回结果的 Response 的数据量要大些,从而导致导致了每秒中处理不了那么多请求,因为网卡流量存在瓶颈
-
- 当压测端的网卡有 4 个千兆网卡了之后,施压端的网卡流量就到瓶颈了,这个时候就需要调整施压端了。
- 4 个网卡绑定后,压测短连接的时候,发现 si 已经到 100%,并且是固定的几个 CPU,这个就说明网卡绑定重复了。
- 网卡重新绑定没有重复之后,si 有改善,整体性能也稍有提高
单机 24 核下,单千兆网卡的场景下,网卡先出现瓶颈; 4 个千兆网卡的场景下,CPU si 软中断先出现瓶颈。
压测时候,要关注大包、小包的不同处理,对于小包,CPU 消耗会更多,因为软中断问题、解包头、校验包数据等层面的问题。 sar 观察数据的时候,一般而言,rxpck/s 和 txpck/s 只需要关注数据而不会存在瓶颈,这个的瓶颈会建立在 CPU 上;而需要关注的是 rxkB/s 和 txkB/s ,这个决定了网卡流量带宽的上限。不仅仅是要观察服务端,还要看客户端是否有瓶颈(CPU、网卡带宽)、错误情况等
关注 Nginx CPU 消耗是否均匀
- 正常而言,nginx 的各个 worker 进程的 CPU 消耗应该都要比较均匀,如果相差 10% 以上,甚至 20% 以上,那么就一定存在 CPU 消耗不均的问题。nginx 目前的版本会使得 CPU 不均,因为关闭了 accept_mutex,正常的话,各个 worker 进程应该都是要差不多的 CPU 消耗,如果开启accept_mutex on;会均匀到前面几个 nginx worker 进程。
- 最优的姿势是开启 reuseport,但是这个需要注意要和 dynamic upstream 一起使用,否则如果出现频繁 reload 则会导致出现大量 RST。
关注 CPU 超线程
- 禁能、使能 CPU 超线程,在 nginx 单进程的情况下,并没有明显差异
- 压测时候, 是否关闭超线程,没有明显差异
关注单机多实例
- 单机单实例性能达到极限后或者出现瓶颈后,单机多实例还是一样,没有提升; 单机单实例没有性能瓶颈的话,多实例可以提升性能
关注施压端
- 压测的时候,要找到一个性能拐点;如果一上来就是瓶颈了,那么还需要往回调,直到找到一个最佳的性能拐点。
长连接的时候,如果 wrk 给的线程数、并发数太大,反而会使得 Nginx 只有 1 个 worker 进程的时候的性能降低; 短进程的时候,wrk 端的系统参数 net.ipv4.tcp_tw_recycle 要设置为 1,让端口复用,否则会出现一些连接错误
因此一个过程就是会将施压端的压力(线程数、并发数)会减少、增大,从而观察 Nginx 服务端的数据,然后得到最佳性能数据
- wr 压力上不去? 要想为啥上不去? CPU遇到瓶颈了,还是内存遇到瓶颈了? 如果cpu的话,那么怎么给更多CPU?当然的线程数。但是线程数也要和施压方的CPU核心数匹配。
- top -H 看线程,要让每个线程都没跑满,这样才能发挥最大的性能,如果每个线程跑满了,那么wrk则无法发挥最大性能,也就是无法提供最高压力。如果每个线程都没跑满,但是QPS 还是上不去,那么就是Nginx这边性能的问题了。
压测时必须要观察的指标
CPU【top】
top ,观察 CPU 消耗情况,同时也要观察每个 CPU 核数的情况,并且关注 si 软中断的数据,si 到了 100% 就有问题了
网卡带宽【sar -n DEV 1 100 |grep em1】
sar -n DEV 1 100 |grep em1
观察网卡带宽情况,看网卡带宽是否到了瓶颈
然后可以 ifconfig 查看是否有丢包之类的。
每秒建连数【netstat -s |grep active】
netstat -s |grep active
6262441249 active connections openings
通过 netstat -s |grep active
获取当前活跃的连接,然后做差值。
5W 短连接的 QPS, 如果还有upstream是短连接,那么每秒建连数应该是10W左右
连接队列 【ss -lnt 】
ss -lnt
ss -lnt |grep -E ":6001|:6002"
State Recv-Q Send-Q Local Address:Port Peer Address:Port
- 当套接字处于监听状态(Listening)时,
- Recv-Q 表示 syn backlog 的当前值。
- Send-Q 表示最大的 syn backlog 值。
- 连接队列如果太小,那么需要调整系统和 nginx 的配置
磁盘 IO
Nginx 调优的一些经验
Nginx 的性能指标
相关基础指标:
-
Requests per second (RPS) : nginx 每秒处理的请求数(也就是: QPS)
RPS for HTTP Requests: nginx 每秒处理的 http 请求数
RPS for HTTPS Requests (SSL/TLS transactions per second )(TPS) : nginx 每秒处理的 https 请求数
-
要关注响应数据在 0 - 1 - 10 - 100 KB 的不同情况的表现
- 0KB 表示一个空的 http 响应,比如返回 302 错误码
-
Connections per Second (CPS) : nginx 每秒处理的新建连接请求数
- 包括 http 和 https
Throughput:吞吐量,反应 nginx 可以处理的数据量的大小的能力
latency: 延迟和延迟分布
其他关注点:
-
关注 CPU 核数从 1 - n 下,nginx 性能的表现
- 利用 taskset,可以将一个 wrk 进程绑定到一个 CPU 核上;可以准确的测试不同 CPU 核下的性能情况
关注 nginx 的角色是 webserver 或者 反向代理的不同表现
连接数,有时候也会被称为并发数,指的是同时在服务中的请求数。也就是那些已经发送请求(Request),但是还没有收完应答(Response)的请求数量。
Nginx 必须要调整的参数
Nginx 必须要调整的参数:
worker_processes auto;
worker_rlimit_nofile 10240;
worker_connections 10240;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 300s;
keepalive_requests 1000000;
建议调整的参数:
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
Linux 系统必须要调整的参数
conntrack 参数
一般,设置 nf_conntrack_max 为 200w, nf_conntrack_buckets 为 1/4 或者 1/2 倍 nf_conntrack_max,防止桶太大导致性能影响。
[[email protected] ingress]$ cat /proc/sys/net/netfilter/nf_conntrack_buckets
524288
[[email protected] ingress]$ cat /proc/sys/net/netfilter/nf_conntrack_max
2097152
backlog 队列
- net.core.somaxconn
- 可以排队等待 Nginx 接受的最大连接数。通常如果太小导致了 Nginx 性能问题可以查看内核日志发现这个状态
- 配合 NGINX listen 指令一起调整。
- net.core.netdev_max_backlog
- 数据包在发送给 CPU 之前被网卡缓冲的速率;增加该值可以提高具有高带宽的机器的性能
echo 32768 > /proc/sys/net/core/somaxconn
echo 819200 > /proc/sys/net/ipv4/tcp_max_syn_backlog
文件描述符
-
sys.fs.file-max
- Linux 系统允许的最大文件描述数
-
nofile
- 应用层面允许的最大文件描述符数,一般设置
/etc/security/limits.conf
文件
- 应用层面允许的最大文件描述符数,一般设置
端口 【修改 /etc/sysctl.conf,然后 sysctl -p 生效】
-
net.ipv4.ip_local_port_range
- port 端口的范围
-
对压测端而言,如果是短链接
- net.ipv4.tcp_tw_reuse = 1
- 表示开启端口复用。允许将TIME-WAIT sockets重新用于新的 TCP接,默认为0,表示关闭;
- net.ipv4.tcp_tw_recycle = 1
- 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
- net.ipv4.tcp_tw_reuse = 1
网卡队列、CPU 软中断 si
- 单机 20-24 核下,单千兆网卡的场景下,网卡先出现瓶颈; 4 个千兆网卡的场景下,CPU si 软中断先出现瓶颈。
- 4 个网卡绑定后,压测短连接的时候,发现 si 已经到 100%,并且是固定的几个 CPU,这个就说明网卡绑定重复了。网卡重新绑定没有重复之后,si 有改善,整体性能也稍有提高
- CPU idle 为 0 不会有问题,只有 si 为 100% 才会有问题
- si 到 100%,表示 CPU 在大量处理软中断,这个时候,说明网卡软中断和 CPU 绑定这个有些瓶颈。要么就是网卡队列不够,要么就是 CPU 核心太少,要么就是网卡队列和 cpuset 对进程的 CPU 绑定重复了。
【"欢迎关注我的微信公众号:Linux 服务端系统研发,后面会大力通过微信公众号发送优质文章"】