Skip to content

Nginx 优化

连接数

events 模块中包含nginx中所有处理连接的设置

worker_connections 设置可由一个 worker 进程同时打开的最大连接数。最大客户数也由系统的可用socket连接数限制(~ 64K)

连接数包括代理服务器的连接、客户端的连接等,Nginx 总并发连接数 = worker_process * worker_connections

查看最大连接数

进程的最大连接数受 Linux 系统进程的最大打开文件数限制,只有执行了 ulimit -HSn 65535 之后 worker_connections 才能生效, 默认情况下服务器的 ulimit -n 的值是 1024

bash
# 查看系统级的最大限制
cat /proc/sys/fs/file-max

# 查看用户级的限制 
ulimit -n

查看 nginx 当前连接数

  • 通过 nginx 的 status 模块

stub_status : 提供访问基础状态信息

通过命令查看

  • 查看当前的连接数
bash
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

返回的数据

TIME_WAIT 17
ESTABLISHED 3254
LAST_ACK 236
FIN_WAIT_1 648
FIN_WAIT_2 581
CLOSING 7
CLOSE_WAIT 4916

数据解析

CLOSED       // 无连接是活动的或正在进行
LISTEN       // 服务器在等待进入呼叫
SYN_RECV     // 一个连接请求已经到达,等待确认
SYN_SENT     // 应用已经开始,打开一个连接
ESTABLISHED  // 正常数据传输状态/当前并发连接数
FIN_WAIT1    // 应用说它已经完成
FIN_WAIT2    // 另一边已同意释放
ITMED_WAIT   // 等待所有分组死掉
CLOSING      // 两边同时尝试关闭
TIME_WAIT    // 另一边已初始化一个释放
LAST_ACK     // 等待所有分组死掉

优化 TimeWait 和 NotEstablished

这个选项的意义是等待连接数量的最大值, 如果 TCP 连接中 TIME_WAIT 的数量超过了此配置项, 对于 nginx 来说则会存在 500 的异常

关于 tcp_max_tw_buckets 选项

🔗 https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

系统同时持有的Time-Wait套接字的最大数量。如果超过此数字,Time-Wait套接字将立即被销毁,并打印警告。此限制仅存在于防止简单的DoS攻击,您 不得 人为降低限制,而应该增加它(可能在增加安装的内存后),如果网络条件允许的条件下需要超过默认值
一般的说明是默认值 : 180000, 可能某些云机由于配置问题值可能有差异

基于伙玩的实例

未优化之前的连接数 NotEstablished 的数量到达了一定的峰值, 然后处于持平状态, 在这个时候服务器日志会报 500 错误

这个地方是因为 TW 到了峰值, 因为使用的云机, 所以值默认为 5000, 我们陆续调整值可以看到连接数持平的瓶颈和这个参数有关系

net.ipv4.tcp_max_tw_buckets = 8000
  • 调整为 5000
  • 调整为 6000
  • 调整为 8000

可以看到调整值可持平值有正向关系, 这个用来解决 TW 的数据上限问题

参考文章

🔗 https://help.aliyun.com/document_detail/41334.html

worker_processes 进程数

🔗 http://nginx.org/en/docs/ngx_core_module.html#worker_processes

定义了nginx对外提供web服务时的worder进程数。最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式。不能确定的时候,将其设置为可用的CPU内核数将是一个好的开始(设置为 auto 将尝试自动检测它)

最大文件数限制

报错信息

2023/07/25 16:28:39 [alert] 7269#7269: *109277532 socket() failed (24: Too many open files) while connecting to upstream, client: 39.144.92.101

基本的意思是 nginx 进程打开了太多的文件

系统中默认的设置是 65535

ulimit

Provides control over the resources available to the shell and to processes started by it, on systems that allow such control.

即设置当前shell以及由它启动的进程的资源限制, 这里的资源限制分为三个部分: 系统限制, 服务器限制, 进程限制

file-max : 系统限制

/proc/sys/fs/file-max
This file defines a system-wide limit on the number of open files for all processes. (See
also setrlimit(2), which can be used by a process to set the per-process limit,
RLIMIT_NOFILE, on the number of files it may open.) If you get lots of error messages
about running out of file handles, try increasing this value
file-max 是设置系统所有进程一共可以打开的文件数量 。同时一些程序可以通过 setrlimit 调用,设置每个进程的限制。如果得到大量使用完文件句柄的错误信息,是应该增加这个值

我们查看下这个值的大小

$ sysctl -n -e fs.file-max
9223372036854775807

ulimit 在系统的限制

由它启动的进程的资源限制

$ ulimit -Hn
65535
$ ulimit -Sn
65535

nginx 程序的限制

我们找到nginx 的进程 id, 查看下限制, 这里的 limit 应当设置为何 ulimit 的值一致

$ ps -ef |grep 'nginx: master'
root     7206    1  0 Jul07 ?   00:00:00 nginx: master process /usr/sbin/nginx

$ cat /proc/7206/limits
Limit                     Soft Limit           Hard Limit           Units
...
Max open files            1024                 524288               files
...

# 子进程数量
$ cat /proc/31658/limits
Limit                     Soft Limit           Hard Limit           Units
...
Max open files            1024                 4096                 files
...

这里查看到 Soft Limit 的数据是 1024, 这里需要调整 nginx 的程序限制 worker_rlimit_nofile , 这里重新修改之后重新加载一下 🔗 官方文档说明

worker_rlimit_nofile **** 更改 worker 进程的最大打开文件数限制。如果没设置的话,这个值为 1024 的限制, 设置后你的操作系统和Nginx可以处理比 ulimit -a 更多的文件,所以把这个值设高,这样nginx就不会有 too many open files 问题了, 这里设置的值应当和 ulimit -a 一致

// nginx.conf
...
worker_processes  auto;
worker_rlimit_nofile 65535;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  10240;
}
...
$ nginx -s reload

看下 worker 的 limits 数据

$ cat /proc/4191488/limits
Limit                     Soft Limit           Hard Limit           Units
...
Max open files            65535                65535                files
...

配置完毕, 等待查看效果

nginx upstream prematurely closed connection while reading response header from upstream

这个问题是从上游读取数据失败

原因是, nginx 无法正常返回数据, 未给 /var/lib/nginx 目录以正常的权限, 导致上游数据无法正常返回.

参考文章