最新消息:

高并发状态下nginx的配置(20万并发)

IT技术 ipcpu 75浏览

高并发状态下nginx的配置(20万并发).md

一、概述

最近业务量比较大,nginx出现了十六七万将近二十万并发(ESTABLISH连接数)的情况,所以对20万以下并发,nginx需要注意哪些配置进行了整理:

二、操作系统基础优化

网上一大堆,基本就是改sysctl.conf,需要注意的是

net.ipv4.tcp_max_tw_buckets = 940000
net.ipv4.tcp_tw_recycle=0
net.ipv4.ip_local_port_range = 1024 65000
#端口范围尽量大一些

三、nf_conntrack的配置

如果启用了nf_conntrack,并且配置的数值较小,那么会遇到

nf_conntrack: table full, dropping packet

如果可能的话,建议关闭nf_conntrack,设置NOTRACK或者调大数值。
做openstack云计算的同事推荐配置

nf_conntrack_max = 4194304 
nf_conntrack_buckets = 1048576
nf_conntrack_tcp_timeout_time_wait = 60

也可以参照本站以前的文章:
https://www.ipcpu.com/2015/06/nf_conntrack-table-full/

四、文件打开数配置

如果你的文件打开数是65535,那么应该先遇到的错误是”Too many open files”

 error: 2018/06/15 17:03:51 [crit] 3325#0: accept4() failed (24: Too many open files)

需要调整操作系统的/etc/security/limits.conf以及附属文件。
在nginx层面有2个参数也需要调整

worker_rlimit_nofile 512000;
##@@worker进程的最大打开文件数限制。
worker_connections 151200;
##@@worker进程可以保持的最大并发连接。官方文档明确标出,作为代理使用时,这个值包含"nginx与客户端的连接"和"nginx与upstream的连接"。

网上有个公式:
max_clients = worker_processes * worker_connections / 2;
(部分文档是除以4,是考虑浏览器并发数为2)
这个参数解决了,基本上七八万的ESTABLISH是没问题了。

五、端口耗尽的问题

如果并发数继续往上增长,可能出现如下错误:

2018/06/16 08:37:35 [crit] 27744#0: *137027418 connect() to 10.140.2.47:443 failed (99: Cannot assign requested address) while connecting to upstream, client: 10.140.2.200, server: 0.0.0.0:9443, upstream: "10.140.2.47:443", bytes from/to client:0/0, bytes from/to upstream:0/0

很明显端口耗尽,没有可以资源了。
这里的端口耗尽,并不是指1-65535端口,而是socket五元组,如下

对于客户端访问nginx的连接来说,

源IP和源端口都是随机的,目的IP(nginx本机IP)和目的端口(nginx本机服务端口)是固定的,这样理论上来说,是没有限制的。

对于nginx访问upstream来说,

源IP固定(nginx本机IP),源端口随机,目的IP和目的端口(upstream地址)需要看upstream的数量,总数就是6万随机端口乘以upstream的个数。

如果upstream的个数很少,那就会出现端口耗尽,例如5个upstream地址,那么总数就是6万*5=30万(实际只有80-90%)大约25万。

我们在nginx服务器上使用 “ss -n” 也发现确实是按照五元组使用的,例如下面的13958本机端口就是用了两次,产生了两个socket连接。

ESTAB 0 0 172.28.4.173:13958 172.28.4.161:3000               
ESTAB 0 0 172.28.4.173:13958 172.28.4.162:3000 

那么如何解决端口耗尽的问题呢?
一方面可以在upstream机器上增加IP地址或者端口,
另一方面也可以在nginx主机上增加IP地址,然后使用nginx的proxy_bind指定源地址。

五、系统内存

在操作系统层面每个TCP连接会占用3k-10k的内存,以20万来计算,需要2G内存。nginx程序本身还要消耗内存,特别是nginx反向代理POST请求比较多的情况,20万连接情况下推荐16G内存配置。

六、深度追问

TCP连接会不会占用文件描述符?

处在ESTABLISH状态的TCP连接,是会占用文件描述符的。而处在TIME_WAIT等非连接状态的TCP连接不会占用。
注意:CLOSE_WAIT状态也会占用文件描述符(怎么看?lsof !)

关于TIME_WAIT数量过大会有什么影响?

这个担心是多余的,我目前机器上TIME_WAIT数量在60万左右,tcp_max_tw_buckets 设置的是94万,由于TIME_WAIT占用内存很小,并且不占用文件描述符,目前没发现有什么问题。

关于upstream中的keepalive选项,什么意思?

线上的nginx代理服务器upstream中的keepalive选项设置为64,但实际运行过程中和后端单台服务器产生了一万多ESTAB连接。查看了nginx官方文档,发现这个值是最大的idle(空闲)数据,只有用完的连接才会回收。

The connections parameter sets the maximum number of idle keepalive connections to upstream servers that are preserved in the cache of each worker process. When this number is exceeded, the least recently used connections are closed.

参考资料

https://work-jlsun.github.io/2016/09/01/tunning-nginx-performance.html
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
https://www.cs.utah.edu/~mflatt/past-courses/cs5460/lecture17.pdf

转载请注明:IPCPU-网络之路 » 高并发状态下nginx的配置(20万并发)