👉点击这里申请火山引擎VIP帐号,立即体验火山引擎产品>>>
通常衡量云服务器的网络性能时,会考虑分析Nginx服务的长连接每秒完成请求数以及短连接每秒完成请求数,本文介绍如何获得云服务器Nginx最佳性能的测试方案。
测试工具及版本
本文将在Server端部署Nginx服务,Client端部署Wrk压测工具。
Nginx:高性能的HTTP和反向代理的轻量级Web服务器,本文以Nginx 1.18.0为例。
Wrk:轻量级的HTTP基准测试工具,本文以wrk [epoll] Copyright (C) 2012 Will Glozer为例。
测试指标
Requests/sec:平均每秒完成的请求数,该值越大表示对应的Nginx性能表现更优。
测试环境
两台相同规格的ECS实例,分别作为服务端(Sever)和客户端(Client),具体配置如下表所示。
创建实例请参见通过向导购买实例,更多实例规格请参见实例规格介绍。
测试示例 | Sever端 | Client端 |
---|---|---|
实例规格 | ecs.g3i.2xlarge | ecs.g3i.2xlarge |
镜像类型 | Ubuntu 22.04 | Ubuntu 22.04 |
实例数量 | 1 | 1 |
操作步骤
步骤一:Server端部署并启动Nginx服务
登录Sever端云服务器。
部署Nginx服务。
执行如下命令,创建Nginx部署文件。
vim nginx_install.sh按i进入编辑模式,并输入以下内容。
#!/bin/bash # install nginx if which yum; then rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm yum -y install nginx elif which apt; then apt update apt -y install nginx fi # close accesslog mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.origin sed "/ *access_log.*/c\access_log off;" /etc/nginx/nginx.conf.origin > /etc/nginx/nginx.conf # prepare demo file html_dir=$(grep root /etc/nginx/nginx.conf |grep -v "#"|awk '{print $2}'|sed "s/;//") if [ ! ${html_dir} ];then html_dir=$(grep root /etc/nginx/sites-available/default|grep -v "#"|awk '{print $2}'|sed "s/;//") fi echo "nginx html dir is ${html_dir}" cd ${html_dir} dd if=/dev/urandom of=1k bs=1k count=1 dd if=/dev/urandom of=4k bs=4k count=1 dd if=/dev/urandom of=1M bs=1M count=1 echo "hello">hello echo "install and prepare nginx finish" nginx -v
按Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
执行如下命令进行安装。
bash nginx_install.shServer 端启动 Nginx 服务。
执行如下命令创建运行文件nginx_run.sh。
vim nginx_run.sh按i进入编辑模式,并输入以下内容。
#!/bin/bash # run # change ulimit ulimit -n 65535 ulimit -n # start nginx service systemctl stop nginx systemctl start nginx systemctl status nginx echo "start nginx finish"
执行如下命令,启动Nginx服务。
bash nginx_run.sh
步骤二:优化实例配置以获取最佳的Nginx性能(可选)
具体优化项及相关操作步骤请参见最佳配置。
步骤三:Client端部署Wrk工具并创建测试脚本
登录Client端云服务器。
部署Wrk工具。
执行如下命令创建Wrk部署文件。
vim wrk_install.sh按i进入编辑模式,并输入以下内容。
#!/bin/bash if which wrk; then echo 'wrk is already installed' && exit; fi if which yum;then yum install -y unzip python3; elif which apt ; then apt update && apt -y install unzip python3; fi cd $(dirname $0) #install wrk while true do wget https://github.com/wg/wrk/archive/refs/heads/master.zip && break done unzip master.zip cd wrk-master/ make cp wrk /usr/bin/ whereis wrk
按Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
执行如下命令进行安装。
bash wrk_install.sh创建测试脚本wrk_run.sh。
执行如下命令创建测试脚本。
vim wrk_run.sh按i进入编辑模式,并输入以下内容。
#!/bin/bash ulimit -n 65535 if [ $# -lt 1 ]; then echo 'Usage: bash wrk_run.sh $serverIP [$threadNums] [$connNums]' exit elif [ $# -gt 3 ]; then echo 'Usage: bash wrk_run.sh $serverIP [$threadNums] [$connNums]' echo "Error: The number of parameters must be between 1-3" exit fi dest_host=$1 if [ $# -eq 2 ]; then wrk_thread=$2 elif [ $# -eq 3 ]; then wrk_thread=$2 wrk_conn=$3 fi if [ ! ${wrk_thread} ];then wrk_thread=128; fi if [ ! ${wrk_conn} ];then wrk_conn=1024; fi for data in hello do # long connection echo "$(date) BENCHMARK STATR to stress nginx_long_ops[$data] with wrk ${dest_host} ${wrk_thread} ${wrk_conn} " wrk -t ${wrk_thread} -c ${wrk_conn} -d 60 http://${dest_host}/$data echo "" # short connection echo "$(date) BENCHMARK STATR to stress nginx_short_ops[$data] with wrk ${dest_host} ${wrk_thread} ${wrk_conn} " wrk -t ${wrk_thread} -c ${wrk_conn} -d 60 -H "Connection: close" http://${dest_host}/$data done;
按Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
步骤四:Client端执行脚本测试并获取结果
获取 Server端的私网IP地址,然后在Client端执行如下命令进行测试。
bash wrk_run.sh <serverIP> <threadNums> <connNums>测试结果如下,其中可重点关注Requests/sec项,表示平均每秒完成的请求数,该值越大代表对应的 Nginx 性能表现更优。
详细的测试结果说明如下。Tue Apr 25 02:50:05 PM CST 2023 BENCHMARK STATR to stress nginx_long_ops[hello] with wrk $serverIP 128 1024 Running 1m test @ http://$serverIP/hello 128 threads and 1024 connections (共128个线程 1024个链接) Thread Stats Avg Stdev Max +/- Stdev (平均值) (标准差) (最大值)(处于标准差内的比例) Latency 1.03ms 182.06us 19.56ms 95.21% (延迟) Req/Sec 7.83k 550.46 37.53k 99.67% (每秒请求数) 59976763 requests in 1.00m, 14.74GB read (共运行1min,完成59976763个请求,读取了14.74GB数据) Requests/sec: 997958.48 (平均每秒完成请求数) Transfer/sec: 251.21MB (平均每秒传输字节大小)
serverIP(必填):Sever端云服务器的私网IP地址,可在云服务器控制台实例列表页的“主IPv4地址”列查看。
threadNums(选填):创建的线程数,默认128。
connNums(选填):创建的连接数,默认1024。
最佳配置
Nginx相关性能受到多方面因素影响,例如:Nginx服务配置参数、内核参数、网卡队列等,您可以参考下文优化云服务器配置以获得最佳的Nginx性能体验。
关闭napi_tx
关闭napi_tx后,可以减少网卡发包操作时的硬中断及软中断数量,提升Nginx性能。
该特性仅在 Linux内核版本 ≥ 5.3 时默认开启,您可以运行uname -r命令查看内核版本并按以下方式关闭napi_tx。
Ubuntu
# 关闭napi_tx: rmmod virtio_net && modprobe virtio_net napi_tx=0 && systemctl restart systemd-networkd.service # 打开napi_tx: rmmod virtio_net && modprobe virtio_net napi_tx=1 && systemctl restart systemd-networkd.service
Debian
# 关闭napi_tx: rmmod virtio_net && modprobe virtio_net napi_tx=0 && systemctl restart networking.service # 打开napi_tx: rmmod virtio_net && modprobe virtio_net napi_tx=1 && systemctl restart networking.service
CentOS
# 关闭napi_tx: rmmod virtio_net && modprobe virtio_net napi_tx=0 && systemctl restart nmcli c reload # 打开napi_tx: rmmod virtio_net && modprobe virtio_net napi_tx=1 && systemctl restart nmcli c reload
执行cat /sys/module/virtio_net/parameters/napi_tx,返回N代表napi_tx关闭成功。
缓解争抢情况
大规格的机型随着CPU核数的增多,会出现争抢情况影响Nginx性能,主要包括了针对html文件的争抢和套接字(Socket)的争抢,以下将对这两种争抢情况提供相应解决方案,以提高Nginx性能。
方案一:修改Nginx worker数并开启reuseport
Sever端部署Nginx服务后,您可以开启Nginx的reuseport选项,允许多个套接字(Socket)监听同一端口,从而减少争抢;也可以适当调整Nginx worker进程数以降低html访问文件的争抢,从而提高Nginx性能,不同规格的实例,Nginx性能最佳时的worker数如下。
实例规格 | 长连接最佳worker数 | 短连接最佳worker数 |
---|---|---|
ecs.g3i.2xlarge(8 vCPU) | 8 | 8 |
ecs.g3i.8xlarge(32 vCPU) | 12 | 6 |
ecs.g3i.16xlarge(64 vCPU) | 13 | 13 |
修改Nginx worker数并开启reuseport的方法如下:
执行如下命令打开/etc/nginx/nginx.conf配置文件。
vim /etc/nginx/nginx.conf按i进入编辑模式。
修改Nginx worker数并开启reuseport。
根据规格修改worker_processes的值。
在配置文件末尾添加以下内容开启reuseport。
http{ server{ listen 80 reuseport; listen [::]:80 reuseport; } }
按Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
执行如下命令重启Nginx服务,使操作生效。
systemctl restart nginx.service
方案二:安装irqbalance-ng
对于Nginx服务,推荐参考网卡中断绑定安装irqbalance-ng自动配置物理网卡中断,以达到中断负载均衡的效果,提升网络性能。
关闭sniffer
执行如下命令查看是否开启sniffer。
cat /proc/net/ptype若回显如下,表示未开启,跳过此操作。
若回显如下,表示已开启,执行下一步。
执行如下命令,确认是否具有dhclient进程。
ps aux | grep dhclient
回显如下,表示具有 dhclient 进程,执行如下命令终止 dhclient 进程即可关闭sniffer。
kill -9 <process_id>