一、测试内容
本次压力测试针对微校平台的nginx前端处理能力进行,评估nginx处理吞吐量
二、测试方法
测试方法采用apache ab软件,在3台client发起对单一nginx服务的压测,模拟大并发html访问。
每个client启动500并发,发起50000次请求。每次测试总共处理1500并发,150000次请求。
ab命令:
三、测试环境
所有测试服务器都是金山云虚拟主机
Nginx服务器:wx-dev-web,2核cpu,4g内存
Client服务器:wx-dev-test01,wx-dev-test02,wx-dev-officia,每服务器2核cpu,4g内存
网络带宽:千兆内网
四、参数及名词解析
- 压测结果名词
- Requests per second(QPS):吞吐量,即每秒处理请求的数量。
- Transfer rate:传输流量,单位KB/s,反映网络传输压力
- 统计均值:取每次测试样本的三个host的和除以样本数,取得的均值,公式:(样本1+样本2+样本3)/3
- Nginx参数
- worker_processes:nginx 进程数,建议按照cpu 数目来指定。
- worker_cpu_affinity:为每个进程分配cpu。
- worker_rlimit_nofile:一个nginx 进程打开的最多文件描述符数目,使用系统参数ulimit -n指定也可以。
- use epoll:使用epoll 的I/O 模型,Linux内核2.6版本及以后的系统推荐使用。
- worker_connections:每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections
- accept_mutex:一个请求到达后,由所有worker争抢还是指定worker处理。
- access_log off:关闭access log写入,能减少一点io等待压力。
- OS内核参数
- net.ipv4.tcp_max_tw_buckets:参数用来设定timewait的数量,默认是180000,这里设为6000。
- net.ipv4.ip_local_port_range:选项用来设定允许系统打开的端口范围。
- net.ipv4.tcp_tw_recycle:选项用于设置启用timewait快速回收。
- net.ipv4.tcp_tw_reuse:选项用于设置开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接。
- net.ipv4.tcp_syncookies:选项用于设置开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies进行处理。
- net.core.somaxconn:选项默认值是128, 这个参数用于调节系统同时发起的tcp连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此,需要结合并发请求数来调节此值。
- net.core.netdev_max_backlog:选项表示当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数目。
- net.ipv4.tcp_max_orphans:选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立连接将立即被复位并打印出警告信息。这个限制只是为了防止简单的DoS攻击。不能过分依靠这个限制甚至人为减小这个值,更多的情况是增加这个值。
- net.ipv4.tcp_max_syn_backlog:选项用于记录那些尚未收到客户端确认信息的连接请求的最大值。对于有128MB内存的系统而言,此参数的默认值是1024,对小内存的系统则是128。
- net.ipv4.tcp_synack_retries:参数的值决定了内核放弃连接之前发送SYN+ACK包的数量。
- net.ipv4.tcp_syn_retries:选项表示在内核放弃建立连接之前发送SYN包的数量。
- net.ipv4.tcp_fin_timeou:t选项决定了套接字保持在FIN-WAIT-2状态的时间。默认值是60秒。正确设置这个值非常重要,有时候即使一个负载很小的Web服务器,也会出现因为大量的死套接字而产生内存溢出的风险。
- net.ipv4.tcp_keepalive_time:选项表示当keepalive启用的时候,TCP发送keep
五、测试数据
测试一
原始参数不做优化,只有业务配置,nginx的基本性能。从OS监控可以看到,资源消耗最大是CPU,其中sys比usr高,说明nginx进程对内核调用非常频繁。
样本 | Requests per second | Transfer rate | 更新 | 删除 | 95% Line | 99% Line | Min | Max | Error % | Throughput | KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|
host1 | host2 | host3 | host1 | host2 | host3 | 0 | 2430 | 0.00% | 81.1 | 11.6 | |
1 | 5144 | 4998 | 5163 | 1214 | 1180 | 1220 | 0 | 2415 | 0.00% | 81.1 | .5 |
2 | 5086 | 4773 | 4794 | 1202 | 1128 | 1133 | 10 | 8164 | 0.00% | 81.2 | .0 |
3 | 5789 | 5245 | 5380 | 1368 | 1239 | 1271 | 3 | 4488 | 0.00% | 81.1 | .2 |
统计均值 | 15457 | 3652 | 510 | 3250 | 4163 | 5325 | 0 | 8164 | 0.00% | 323.7 | 12.3 |
测试二
Nginx配置文件参数优化,包括基本优化work、connection、epoll、access_log off等。
从结果看和没优化也差不了多少,硬件资源是,特别CPU消耗是瓶颈,相同压力下比测试一的CPU消耗更大。
样本 | Requests per second | Transfer rate | 更新 | 删除 | 95% Line | 99% Line | Min | Max | Error % | Throughput | KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|
host1 | host2 | host3 | host1 | host2 | host3 | 0 | 2430 | 0.00% | 81.1 | 11.6 | |
1 | 5968 | 6160 | 5971 | 1375 | 1419 | 1376 | 0 | 2415 | 0.00% | 81.1 | .5 |
2 | 6127 | 6086 | 6087 | 1412 | 1402 | 1402 | 10 | 8164 | 0.00% | 81.2 | .0 |
3 | 6073 | 6063 | 5991 | 1399 | 1397 | 1380 | 3 | 4488 | 0.00% | 81.1 | .2 |
统计均值 | 18175 | 4187 | 510 | 3250 | 4163 | 5325 | 0 | 8164 | 0.00% | 323.7 | 12.3 |
nginx参数文件:
#user nobody; worker_processes 2; #error_log logs/error.log; error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { use epoll; worker_connections 65530; accept_mutex off; } http { include /usr/sbin/nginx/conf/mime.types; default_type application/octet-stream; #lua_package_path '/usr/sbin/nginx/lua/?.lua;;/path/to/lua-resty-kafka/lib/?.lua;;/path/to/lua-resty-redis/lib/?.lua;;'; #access_log logs/access.log; access_log off; error_log off; #General Options server_names_hash_bucket_size 128; client_header_buffer_size 64k; large_client_header_buffers 4 128k; server_tokens off; ignore_invalid_headers on; recursive_error_pages on; server_name_in_redirect off; # sendfile on; #TCP Options tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; #size limits gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.0; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; #cache begin proxy_buffering on; proxy_cache_valid any 10m; proxy_cache_path /data/nginxcache levels=1:2 keys_zone=ng-cache:8m max_size=1000m inactive=600m; proxy_temp_path /data/nginxtemp; proxy_buffer_size 4k; proxy_buffers 100 8k; open_file_cache max=65535 inactive=60s; open_file_cache_valid 80s; open_file_cache_min_uses 1; server { listen 80; server_name localhost; location / { index index.html index.htm; root /data/nginx/html/; proxy_cache ng-cache; proxy_cache_valid 200 1h; #aio threads; } } }
OS内核参数:
net.ipv4.tcp_keepalive_time = 600 net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_mem = 786432 1048576 1572864 net.core.wmem_max = 873200 net.core.rmem_max = 873200 net.core.somaxconn = 262144 net.ipv4.tcp_wmem = 8192 436600 873200 net.ipv4.tcp_rmem = 32768 436600 873200 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.tcp_retries2 = 3 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 net.core.netdev_max_backlog = 262144
测试三
不使用apt的nginx,使用源码编译nginx,加入CPU,gcc等编译优化,增加Google tcmollac支持,nginx参数使用测试二参数。
测试使用的参数文件见测试二,Google tcmollac是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配、释放内存造成的性能损耗,并且有效地控制内存碎片。使用tcmollac代替glibc默认的内存管理能提升nginx的内存使用效率。
参考链接:Nginx和TCMalloc
从结果看,QPS有约7%提升,同时CPU消耗稍稍下降。
样本 | Requests per second | Transfer rate | 更新 | 删除 | 95% Line | 99% Line | Min | Max | Error % | Throughput | KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|
host1 | host2 | host3 | host1 | host2 | host3 | 0 | 2430 | 0.00% | 81.1 | 11.6 | |
1 | 6566 | 6576 | 6355 | 1513 | 1515 | 1464 | 0 | 2415 | 0.00% | 81.1 | .5 |
2 | 6849 | 6543 | 6534 | 1578 | 1508 | 1505 | 10 | 8164 | 0.00% | 81.2 | .0 |
3 | 6842 | 6515 | 6394 | 1576 | 1501 | 1473 | 3 | 4488 | 0.00% | 81.1 | .2 |
统计均值 | 19725 | 4544 | 510 | 3250 | 4163 | 5325 | 0 | 8164 | 0.00% | 323.7 | 12.3 |
另外对比测试了开启access log的情况,性能下降约10%,但是相信随着硬件提升,性能损失会更低。
样本 | Requests per second | Transfer rate | 更新 | 删除 | 95% Line | 99% Line | Min | Max | Error % | Throughput | KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|
host1 | host2 | host3 | host1 | host2 | host3 | 0 | 2430 | 0.00% | 81.1 | 11.6 | |
1 | 6036 | 5834 | 5849 | 1391 | 1344 | 1348 | 0 | 2415 | 0.00% | 81.1 | .5 |
2 | 6254 | 5855 | 5854 | 1441 | 1349 | 1349 | 10 | 8164 | 0.00% | 81.2 | .0 |
3 | 6020 | 5924 | 5922 | 1387 | 1365 | 1364 | 3 | 4488 | 0.00% | 81.1 | .2 |
统计均值 | 17849 | 4113 | 510 | 3250 | 4163 | 5325 | 0 | 8164 | 0.00% | 323.7 | 12.3 |
测试四
使用taobao tengine代替nginx,优化参数不变,从结果看QPS有约3%提升。除非对tengine独有的特性有需求,否则不需要特意替换成tengine。
样本 | Requests per second | Transfer rate | 更新 | 删除 | 95% Line | 99% Line | Min | Max | Error % | Throughput | KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|
host1 | host2 | host3 | host1 | host2 | host3 | 0 | 2430 | 0.00% | 81.1 | 11.6 | |
1 | 6762 | 6635 | 6758 | 1571 | 1542 | 1570 | 0 | 2415 | 0.00% | 81.1 | .5 |
2 | 6637 | 6571 | 6918 | 1542 | 1527 | 1608 | 10 | 8164 | 0.00% | 81.2 | .0 |
3 | 6780 | 6697 | 6777 | 1575 | 1556 | 1575 | 3 | 4488 | 0.00% | 81.1 | .2 |
统计均值 | 20178 | 4689 | 510 | 3250 | 4163 | 5325 | 0 | 8164 | 0.00% | 323.7 | 12.3 |
六、结论
- nginx在低配置机器上即使不进行刻意优化也能提供稳定高效的http服务,当然进行优化会更好。
- 并发继续增大后nginx遇到的第一个瓶颈在CPU。
- 使用源码进行重新编译nginx可以使性能得到有效提升。
- taobao tengine性能提升在此次测试环境没有特别明显,但是动态加载模块在运维中有实际意义。
- 有技术文档提到nginx1.9新版本支持SO_REUSEPORT 特性,性能比传统方式提高2倍,需要linux 3.9版本内核才支持,待测试。参考链接:NGINX 1.9.1 中的 Socket 切分
微信赞赏支付宝扫码领红包