nginx压测记录
- 1 概述
- 2 原理
- 3 环境
- 3.1 设备与部署
- 3.2 nginx配置/服务器配置
- 4 netty服务
- 5 步骤
- 6 结果
- 7 写在最后
1 概述
都说nginx的负载均衡能力很强,最近出于好奇对nginx的实际并发能力进行了简单的测试,主要测试了TCP/IP层的长链接负载均衡
2 原理
准备netty服务器与客户端,netty-client每秒向netty-server发送1条数据,netty-server接收各netty-client的数据,检查数据序号的连续性从而检查是否丢包,然后将数据发到内存,再由各数据存储线程将数据存储到本地磁盘,通过数据检查程序也可以检查并提取单个客户端的所有数据,通过随机抽样检查单个客户端发送的数据是否正常
3 环境
3.1 设备与部署
设备 | 操作系统 | 部署服务 |
---|---|---|
服务器1 | centos7 | nginx |
服务器2 | centos7 | netty-server |
服务器3 | centos7 | netty-server |
PC1 | win10/7 | netty-client(10000个) |
PC1 | win10/7 | netty-client(10000个) |
PC1 | win10/7 | netty-client(10000个) |
PC1 | win10/7 | netty-client(10000个) |
PC1 | win10/7 | netty-client(10000个) |
PC1 | win10/7 | netty-client(10000个) |
PC1 | win10/7 | netty-client(10000个) |
3.2 nginx配置/服务器配置
- 若nginx报错accept() failed (24: Too many open files),基本是应为系统对同时打开的文件数做了限制,需要对系统以及nginx都进行配置
系统配置:
查看当前用户可同时打开的文件句柄数
ulimit -n
通过命令进行设置(这样设置服务器重启会失效,但可以在/etc/profile文件追加ulimit -n 65535,只针对当前用户有效)
ulimit -n 65535
通过修改系统配置文件进行设置
修改/etc/security/limits.conf文件,追加如下内容
*代表所有用户,如果想代表某个用户的话,则user soft nofile 65535
soft代表软连接 hard代表硬限制
具体可以参考这篇文章: http://t.csdn.cn/MKZkR
nginx配置
worker_processes 指令控制工作进程数,其默认值为1,这意味着NGINX只运行一个worker。 该值应根据可用内核数,磁盘,网络子系统,服务器负载等更改为最佳值。一般设置为可用的(cpu)核心数。或者,可以将其设置为auto。 这样nginx会自动根据核心数为生成对应数量的worker进程。
worker_rlimit_nofile 同时连接的数量受限于系统上可用的文件描述符的数量,因为每个套接字将打开一个文件描述符。 如果NGINX尝试打开比可用文件描述符更多的套接字,会发现error.log中出现Too many opened files的信息。
worker_connections 该指令设置单个worker进程最大打开的连接数
配置例子内容如下:
其中worker_rlimit_nofile = worker_processes*worker_connections,worker_rlimit_nofile受限于系统的文件句柄数
-
若nginx报错no live upstreams while connecting to upstream
//后续补充/// -
一般情况下nginx配置对优化比较有作用的为一下几项:
1 | worker_processes | nginx进程数,建议按照cpu 数目来指定,一般为它的倍数 |
---|---|---|
2 | worker_cpu_affinity | 为每个进程分配cpu,或者将一个进程分配到多个cpu |
3 | worker_rlimit_nofile | 这个指令是指当一个nginx 进程打开的最多文件描述符数目,理论值应该是系统最多打开文件数 |
4 | worker_rlimit_nofile | 这个指令是指当一个nginx 进程打开的最多文件描述符数目,理论值应该是系统最多打开文件数 |
5 | use epoll | 使用epoll 的I/O 模型 |
6 | worker_connections | 每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections。 |
7 | keepalive_timeout | 超时时间 |
8 | client_header_buffer_size | 客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE 取得。 |
9 | open_file_cache | 这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。 |
10 | open_file_cache_valid | 这个是指多长时间检查一次缓存的有效信息 |
11 | open_file_cache_min_uses | open_file_cache 指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除 |
- 内核参数优化
1 | net.ipv4.tcp_max_tw_buckets | timewait 的数量,默认是180000 |
---|---|---|
2 | net.ipv4.ip_local_port_range | 允许系统打开的端口范围。 |
3 | net.ipv4.tcp_tw_recycle | 启用timewait 快速回收 |
4 | net.ipv4.tcp_tw_reuse | 开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。 |
5 | net.ipv4.tcp_syncookies | 开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。 |
6 | net.core.somaxconn | web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。 |
7 | net.core.netdev_max_backlog | 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。 |
8 | net.ipv4.tcp_max_orphans | 系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。 |
9 | net.ipv4.tcp_max_syn_backlog | 记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M 内存的系统而言,缺省值是1024,小内存的系统则是128。 |
10 | net.ipv4.tcp_timestamps | 时间戳可以避免序列号的卷绕。一个1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。 |
11 | net.ipv4.tcp_synack_retries | 为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。 |
12 | net.ipv4.tcp_syn_retries | 在内核放弃建立连接之前发送SYN 包的数量。 |
13 | net.ipv4.tcp_fin_timeout | 如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180 秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。 |
14 | net.ipv4.tcp_keepalive_time | 当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。 |
4 netty服务
https://github.com/Abstract-Class/netty-test
- netty-server
代码放到了GitHub - netty-client
代码放到了GitHub
5 步骤
- 部署nginx服务并配置反向代理
- 部署netty-server
- 逐个开启netty-client
- 逐个关闭netty-client
- 查看客户端数据连续性统计结果
- 通过数据检查程序抽样检查单个netty-client数据的正确性
6 结果
- 使用两台服务器
连接数 | 服务器具体的状态 | 数据情况 |
---|---|---|
60000 | 服务器正常 | 数据自检正常,抽样检查正常 |
70000 | nginx报错no live upstreams while connecting to upstream | 数据自检正常,数据抽样检查正常 |
- 使用单台服务器
/后续完善//
7 写在最后
笔者水平有限,结果仅供参考