前言

nginx安装后一般都会进行参数优化,网上找找也有很多相关文章,但是这些参数优化对Nginx性能会有多大影响?为此我做个简单的实验测试下这些参数能提升多少性能。

声明一下,测试流程比较简单,后端服务也很简单,测试时间也很短,所以实验并不严谨,结果仅作参考,需要根据实际情况进行参数调优。

文章或有错误和疏漏之处,欢迎各位大佬指出或补充。

环境

IP 操作系统 CPU 内存 部署服务
192.168.3.60 Debian 11.8 4 4 GB wrk
192.168.3.61 Debian 11.8 4 4 GB nginx
192.168.3.62 Debian 11.8 4 4 GB 后端服务
  • nginx:版本1.24.0,编译参数:
./configure --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_gunzip_module --with-http_gzip_static_module --with-stream --with-compat --with-pcre-jit --prefix=/home/admin/apps/nginx
  • 使用wrk进行性能测试,版本为 4.1.0,通过 apt 包管理器安装。
  • 因为主要测试nginx反向代理的性能,所以用go写了个响应"hello world"的api,减少后端服务导致的性能影响。

测试方法:调整nginx参数后多次运行wrk,取平均值。(方法并不严谨,应该用更专业的工具测试运行几小时,将测试数据采用更科学的方法汇总,但时间精力有限,所以采用这个非常简单无脑的实验方法)

实验结果

下面的实验过程主要就是调参数,比较繁琐,所以把实验结果先放到前面。综合配置可参考“实验过程 - 13. 综合调优”。

再次声明,由于测试流程和后端逻辑都比较简单,服务器和网络情况也没严格控制变量所以结果仅供参考。

根据实验结果来看,增大工作进程数能直接提升性能,但不是和CPU核心数一致就能最大化,可能少一点才能达到最佳性能。

除了nginx和系统参数调优,网络和后端服务对性能的影响也很大,而且在大部分ToB业务场景下,后端服务和数据库才是性能短板。

序号 测试方式 Nginx参数优化项 总请求数 平均每秒请求数 平均延迟 优化效果
1 wrk -> 后端 4139984 68884.59 1.66ms +673%
2 wrk -> nginx -> 后端 无,默认配置 534859 8911.30 12.04ms -
3.1 wrk -> nginx -> 后端 设置工作进程数为2 1027745 17127.49 5.95ms +92.19%
3.2 wrk -> nginx -> 后端 设置工作进程数为3 676651 11274.05 8.97ms +26.51%
3.3 wrk -> nginx -> 后端 设置工作进程数为auto(4) 547794 9125.66 11.14ms +2.41%
4 wrk -> nginx -> 后端 设置工作进程数和CPU亲和性为auto 537713 8958.10 11.67ms +0.52%
5 wrk -> nginx -> 后端 在4的基础上设置worker_connections 65535; 532758 8874.85 11.80ms -0.4%
6 wrk -> nginx -> 后端 在5的基础上设置accept_mutex on; 425540 7088.39 15.58ms -20.45%
7 wrk -> nginx -> 后端 在6的基础上设置multi_accept on 591500 9854.77 10.60ms +10.58%
8 wrk -> nginx -> 后端 在7的基础上设置改为upstream 558679 9308.30 12.00ms +4.45%
9 wrk -> nginx -> 后端 在8的基础上设置keepalive 632673 10541.49 10.06ms +18.29%
10 wrk -> nginx -> 后端 在9的基础上设置加一个后端 1006485 16772.08 6.53ms +88.21%
11 wrk -> nginx -> 后端 在2的基础上设置加一个后端 610882 10178.26 10.21ms +14.21%
12 wrk -> nginx -> 后端 在3.1的基础上设置keepalive 1041024 17348.36 5.94ms +94.67%
13 wrk -> nginx -> 后端 在2的基础上设置deferred 596197 9934.61 10.90ms +11.48%
14 wrk -> nginx -> 后端 在2的基础上修改内核参数 581535 9689.91 10.95ms +8.73%
15 wrk -> nginx -> 后端 综合调优 1087151 18115.78 5.94ms +103.28%

单独测试nginx的性能,避免后端服务和网络情况的影响。

序号 Nginx参数优化项 总请求数 平均每秒请求数 平均延迟 优化效果
1 无,默认配置 2327400 38787.61 2.71ms -
2 在1的基础上设置工作进程数为auto 7418729 123633.13 791.04us 218.74%
3 在2的基础上设置CPU亲和性 7437087 123945.45 784.02us 219.54%
4 在3的基础上设置工作进程连接数和多请求 7638947 127300.44 764.67us 228.19%

调整环境,nginx都采用默认配置,只是修改了各组件的位置。因为组件在同一台服务器,资源竞争情况也会影响性能。

环境 总请求数 平均每秒请求数 平均延迟
wrk、nginx和后端各在不同的服务器 534859 8911.30 12.04ms
wrk单独服务器,nginx和后端在同一台服务器 386630 6441.05 16.24ms
wrk、nginx和后端在同一台服务器 402163 6700.38 15.15ms

实验过程

1. 直连后端测试

首先用wrk直接测试后端。因为没有中间商赚差价,所以理论上直连性能会比nginx代理的性能高。

# curl 测试后端响应是否正常
curl http://192.168.3.62:8101 # wrk 直接测试后端服务。线程数为4,连接数为100,测试时间为60秒。
wrk -t4 -c100 -d60s http://192.168.3.62:8101

wrk测试结果

总请求数 平均每秒请求数 平均延迟
4139984 68884.59 1.66ms

2. 使用nginx默认配置代理

nginx刚安装后有一个默认配置,这里只改了location /的配置,修改为反向代理到后端服务

location / {
#root html;
#index index.html index.htm;
proxy_pass http://192.168.3.62:8101;
}

wrk测试结果。相较于后端直连,性能缩水很多

总请求数 平均每秒请求数 平均延迟
534859 8911.30 12.04ms

3. 增加工作进程数

nginx默认工作进程数为1,通过修改worker_processes可指定,一般小于或等于CPU核心数

worker_processes 总请求数 平均每秒请求数 平均延迟 对比默认配置
1(默认) 534859 8911.30 12.04ms -
2 1027745 17127.49 5.95ms +92.19%
3 676651 11274.05 8.97ms +26.51%
auto(4) 547794 9125.66 11.14ms +2.41%

4. 设置CPU亲和性

通过worker_cpu_affinity绑定工作进程和CPU,避免nginx进程在CPU之间切换导致的伪共享带来的性能问题。

nginx配置:

worker_processes  auto;
worker_cpu_affinity auto;

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
537713 8958.10 11.67ms +0.52%

5. 设置worker_connections

worker_connections用于设置每个Nginx进程可处理并发连接的最大数,默认为1024。

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
}

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
532758 8874.85 11.80ms -0.4%

6. 启用互斥锁

nginx配置

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
accept_mutex on;
}

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
425540 7088.39 15.58ms -20.45%

7. 启用多请求支持

默认情况下,每个工作进程一次只接受一个新连接。开启后,每个工作进程将接受所有的新连接。

nginx配置

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
accept_mutex on;
multi_accept on;
}

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
591500 9854.77 10.60ms +10.58%

8. 使用upstream

之前的配置都通过proxy_pass直接反向代理到后端,修改为upstream。

nginx配置

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
accept_mutex on;
multi_accept on;
}
http {
upstream backend {
server 192.168.3.62:8101;
}
server {
location / {
proxy_pass http://backend;
}
}
}

wrk测试结果。性能有所降低,但在多个后端的情况下,还是配置upstream更方便。

总请求数 平均每秒请求数 平均延迟 对比默认配置
558679 9308.30 12.00ms +4.45%

9. 设置keepalive长连接

长连接的存在可以减少建立和关闭TCP连接带来的消耗和延迟。

nginx配置

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
accept_mutex on;
multi_accept on;
}
http {
upstream backend {
server 192.168.3.62:8101;
keepalive 32;
keepalive_requests 2000;
}
server {
location / {
proxy_pass http://backend;
}
}
}

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
632673 10541.49 10.06ms +18.29%

10. 增加后端实例数

分别在默认配置和上一步的基础上,将后端实例数加1。

修改后的nginx配置

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
accept_mutex on;
multi_accept on;
}
http {
upstream backend {
server 192.168.3.62:8101;
server 192.168.3.62:8102;
keepalive 32;
keepalive_requests 2000;
}
server {
location / {
proxy_pass http://backend;
}
}
}

wrk测试结果

配置 总请求数 平均每秒请求数 平均延迟 对比默认配置
默认配置多后端 610882 10178.26 10.21ms +14.21%
默认配置,长连接,工作进程数2 1041024 17348.36 5.94ms +94.67%
修改配置多后端 1006485 16772.08 6.53ms +88.21%

11. 延迟处理新连接

设置deferred参数可延迟处理新连接,加上这个配置后,当用户与nginx服务器建立连接时,只有用户有请求数据时才会将TCP连接状态改为ESTABLISHED,否则就直接丢弃这条连接。通过减少服务器和客户端之间发生的三次握手建立连接的数量来帮助提高性能。

nginx配置

worker_processes  1;
events {
worker_connections 1024;
}
http {
server {
listen 8100 deferred;
}
}

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
596197 9934.61 10.90ms +11.48%

12. 修改内核参数

修改的内核参数如下

# 网卡接受数据包的队列最大长度
net.core.netdev_max_backlog = 24800
# 已经收到syn包,但是还没有来得及确认的连接队列
net.ipv4.tcp_max_syn_backlog = 24800
# 端口监听队列的最大长度, 存放的是已经处于ESTABLISHED而没有被应用程序接管的TCP连接
net.core.somaxconn = 65535
# SYN的超时重传次数
net.ipv4.tcp_syn_retries = 2
# 服务端等待客户端响应ACK的超时重传次数
net.ipv4.tcp_synack_retries = 2
# 作为服务端才拥有TCP Fast Open机制
net.ipv4.tcp_fastopen = 2

nginx的配置为默认配置。

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
581535 9689.91 10.95ms +8.73%

13. 综合调优

开启多请求支持,增加工作进程连接数,配置长连接,增加后端实例,修改内核参数。

如果不想一遍遍修改工作进程数,直接设置为auto最省事,虽然不一定会是最优配置,但总比默认强。

nginx配置

worker_processes  auto;
events {
worker_connections 65535;
multi_accept on;
}
http {
upstream backend {
server 192.168.3.62:8101;
server 192.168.3.62:8102;
keepalive 32;
keepalive_requests 2000;
}
server {
lister deferred backlog=24800;
location / {
proxy_pass http://backend;
}
}
}

内核参数

net.core.netdev_max_backlog = 24800
net.ipv4.tcp_max_syn_backlog = 24800
net.core.somaxconn = 65535
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_fastopen = 2

wrk测试结果

总请求数 平均每秒请求数 平均延迟 对比默认配置
1087151 18115.78 5.94ms +103.28%

14. 单独测试nginx

以上测试场景都有nginx反向代理后端,而网络和后端也会在一定程度上影响nginx性能,所以这里单独测试nginx。

nginx配置

worker_processes  auto;
worker_cpu_affinity auto;
events {
worker_connections 65535;
multi_accept on;
}
http {
server {
location / {
return 200 'hello world';
}
}
}

wrk测试结果。在没有反向代理的情况下,增加工作进程数就能直接提升nginx性能。

序号 Nginx参数优化项 总请求数 平均每秒请求数 平均延迟 优化效果
1 无,默认配置 2327400 38787.61 2.71ms -
2 在1的基础上设置工作进程数为auto 7418729 123633.13 791.04us 218.74%
3 在2的基础上设置CPU亲和性 7437087 123945.45 784.02us 219.54%
4 在3的基础上设置工作进程连接数和多请求 7638947 127300.44 764.67us 228.19%

nginx参数调优能提升多少性能的更多相关文章

  1. Nginx参数调优

    (1)nginx运行工作进程个数,一般设置cpu的核心或者核心数x2 如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 grep ^processor / ...

  2. 【nginx】nginx配置文件结构,内置变量及参数调优

    Nginx的配置文件是一个纯文本文件,它一般位于Nginx安装目录的conf目录下,整个配置文件是以block的形式组织的.每个block一般以一个大括号“{”来表示.block 可以分为几个层次,整 ...

  3. JVM性能参数调优实践,不会执行Full GC,网站无停滞

    原文来自:http://bbs.csdn.net/topics/310110257 本文只做整理记录,供个人学习. 1 JVM参数调优是个很头痛的问题,设置的不好,JVM不断执行Full GC,导致整 ...

  4. Spark Shuffle原理、Shuffle操作问题解决和参数调优

    摘要: 1 shuffle原理 1.1 mapreduce的shuffle原理 1.1.1 map task端操作 1.1.2 reduce task端操作 1.2 spark现在的SortShuff ...

  5. 【转】XGBoost参数调优完全指南(附Python代码)

    xgboost入门非常经典的材料,虽然读起来比较吃力,但是会有很大的帮助: 英文原文链接:https://www.analyticsvidhya.com/blog/2016/03/complete-g ...

  6. php-fpm参数调优

    关于php-fpm.conf参数调优,只对重要的参数进程调优.其它可参数前辈的. http://php.net/manual/zh/install.fpm.configuration.php (官方的 ...

  7. XGBoost参数调优完全指南

    简介 如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧.XGBoost算法现在已经成为很多数据工程师的重要武器.它是一种十分精致的算法,可以处理各种不规则的数据.构造一个使用XGBoost ...

  8. 【Spark篇】---Spark中内存管理和Shuffle参数调优

    一.前述 Spark内存管理 Spark执行应用程序时,Spark集群会启动Driver和Executor两种JVM进程,Driver负责创建SparkContext上下文,提交任务,task的分发等 ...

  9. xgboost 参数调优指南

    一.XGBoost的优势 XGBoost算法可以给预测模型带来能力的提升.当我对它的表现有更多了解的时候,当我对它的高准确率背后的原理有更多了解的时候,我发现它具有很多优势: 1 正则化 标准GBDT ...

  10. spark submit参数调优

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

随机推荐

  1. 使用 Dockerfile 构建生产环境镜像

    传统部署的坑: 1202 年了,如果你连 Docker 都不知道是什么,我建议买一本书看看--或者谷歌一下,博客已经写烂了. 为什么有这篇文章,是因为我在真正做容器化改造的时候,发现公司生产环境存在大 ...

  2. 看element源码学到的小技巧

    中午无休的时候有点无聊, 看了一下昨天clone 的 element-ui 源码, 发现很多优雅之处, 记录一下让我直接用到项目中的一个点 那就是绝对定位的元素放到body 里面的 同级.这么做的好处 ...

  3. 磁盘问题和解决: fsck,gdisk,fdisk等

    错误: Resize inode not valid 对于gpt分区的硬盘一般fsck只能检查分区, 不能用于检查整个硬盘, 但是如果对硬盘设备运行时遇到这样的错误 $ sudo fsck -n /d ...

  4. Print, printf, println的区别

    print 非格式,打印变量的值,不换行 printf 支持格式化输出,不换行 println 非格式,打印变量的值 ,换行

  5. linux下的venv使用

    首先安装该模块: sudo apt-get install python3-venv 之后创建用于存储工程的文件夹 mkdir [filename] 创建环境: python3 -m venv ven ...

  6. UE源码分析:Slate 类鼠标输入处理

    序言 UE4.25版本 本章看一下UE的 "类鼠标"输入处理(其实就是鼠标和触摸的输入,我也没找到专门的术语来代指,英文UE用的是PointerXXX),主要是按下.移动.抬起等相 ...

  7. 用 Python 自动创建 Markdown 表格 - 每天5分钟玩转 GPT 编程系列(4)

    目录 1. 他们居然问我要 Prompts 2. 让 GPT-4 来写代码 2.1 我对 DevChat 说 2.2 DevChat 回答 2.3 我又对 DevChat 说 2.4 DevChat ...

  8. 用React仿钉钉审批流

    引言 这几天帮朋友忙,用了一周时间,高仿了一个钉钉审批流.这个东西会有不少朋友有类似需求,就分享出来,希望能有所帮助.为了方便朋友的使用,设计制作的时候,尽量做到节点配置可定制,减少集成成本.如果您的 ...

  9. redux的三个概念与三大核心

    1.什么是redux?一个组件里可能会有很多的状态,比如控制某个内容显示的flag,从后端获取的展示数据,那么这些状态可以在自己的单个页面进行管理,也可以选择别的管理方式,redux就是是一种状态管理 ...

  10. 部分 Linux 换国内源

    Centos 8 / Redhat 8 换国内源 操作步骤 先把原本的官方 yum 源 删除 或 备份 cd /etc/yum.repos.d/ 备份(Redhat 同理) rename repo r ...