You need to enable JavaScript to run this app.
导航

测试Nginx性能

最近更新时间2023.12.07 17:11:02

首次发布时间2023.05.30 08:34:20

通常衡量云服务器的网络性能时,会考虑分析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.2xlargeecs.g3i.2xlarge
镜像类型Ubuntu 22.04Ubuntu 22.04
实例数量11

操作步骤

步骤一:Server端部署并启动Nginx服务

  1. 登录Sever端云服务器
  2. 部署Nginx服务。
    1. 执行如下命令,创建Nginx部署文件。
      vim nginx_install.sh
    2. 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
      
    3. Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
    4. 执行如下命令进行安装。
      bash nginx_install.sh
  3. Server 端启动 Nginx 服务。
    1. 执行如下命令创建运行文件nginx_run.sh。
      vim nginx_run.sh
    2. 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"
      
    3. 执行如下命令,启动Nginx服务。
      bash nginx_run.sh

步骤二:优化实例配置以获取最佳的Nginx性能(可选)

具体优化项及相关操作步骤请参见最佳配置

步骤三:Client端部署Wrk工具并创建测试脚本

  1. 登录Client端云服务器
  2. 部署Wrk工具。
    1. 执行如下命令创建Wrk部署文件。
      vim wrk_install.sh
    2. 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
      
    3. Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
    4. 执行如下命令进行安装。
      bash wrk_install.sh
  3. 创建测试脚本wrk_run.sh。
    1. 执行如下命令创建测试脚本。
      vim wrk_run.sh
    2. 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;
      
    3. Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。

步骤四:Client端执行脚本测试并获取结果

  1. 获取 Server端的私网IP地址,然后在Client端执行如下命令进行测试。
    bash wrk_run.sh <serverIP> <threadNums> <connNums>

    • serverIP(必填):Sever端云服务器的私网IP地址,可在云服务器控制台实例列表页的“主IPv4地址”列查看。
    • threadNums(选填):创建的线程数,默认128。
    • connNums(选填):创建的连接数,默认1024。

    测试结果如下,其中可重点关注Requests/sec项,表示平均每秒完成的请求数,该值越大代表对应的 Nginx 性能表现更优。
    alt
    详细的测试结果说明如下。

    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
     (平均每秒传输字节大小)
    

最佳配置

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关闭成功。
alt

缓解争抢情况

大规格的机型随着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)88
ecs.g3i.8xlarge(32 vCPU)126
ecs.g3i.16xlarge(64 vCPU)1313

修改Nginx worker数并开启reuseport的方法如下:

  1. 执行如下命令打开/etc/nginx/nginx.conf配置文件。
    vim /etc/nginx/nginx.conf
  2. i进入编辑模式。
  3. 修改Nginx worker数并开启reuseport。
    1. 根据规格修改worker_processes的值。
      alt
    2. 在配置文件末尾添加以下内容开启reuseport。
      http{
              server{
                      listen 80 reuseport;
                      listen [::]:80 reuseport;
              }
      }
      
  4. Esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
  5. 执行如下命令重启Nginx服务,使操作生效。
    systemctl restart nginx.service

方案二:安装irqbalance-ng

对于Nginx服务,推荐参考网卡中断绑定安装irqbalance-ng自动配置物理网卡中断,以达到中断负载均衡的效果,提升网络性能。

关闭sniffer

  1. 执行如下命令查看是否开启sniffer。
    cat /proc/net/ptype
    • 若回显如下,表示未开启,跳过此操作。
      alt
    • 若回显如下,表示已开启,执行下一步。
      alt
  2. 执行如下命令,确认是否具有dhclient进程。
    ps aux | grep dhclient
    回显如下,表示具有 dhclient 进程,执行如下命令终止 dhclient 进程即可关闭sniffer。
    kill -9 <process_id>
    alt