Nginx性能优化

一、性能测试场景

  800 用户数做稳定性压测时,接口大批量返回 500 异常,如下所示

通过上图,我们可以看出来是 Nginx 返回的错误。但是从接口返回看不出太多的细节问题,需要打印 nginix 日志继续定位

二、打印日志分析

  打印 Nginx 日志,可以看到大量的异常信息:Too many open files。看起来是句柄数超出文件限制了

ulimit -a 查看一下 linux 的句柄,发现已经加到最大值: 65535

 

查看 Nginx 进程句柄数,发现也是最大值: 65535

 Linux 句柄和 Nginx 进程句柄都已经放到最大了,为什么还会报错呢?

三、Too many open files问题分析  

  通过分析,其实这个Too many open files反映的并不是句柄数,而是打开文件数。什么是打开文件数呢?Linux 下,有两个值可以代表打开的文件

  1、file-max【最大打开文件数】
  2、ulimit【最大文件句柄数】

通过lsof | grep 应用进程号 | wc -l 查看当前进程一共打开了多少文件,如下图所示,一共打开了 70 多万个。。。

 

然后再通过 ** /proc/sys/fs/file-max*查看一下当前 linux 的 file-max 限制,最大是 10240

对比一下就知道了,打开的文件数远远超出了 linux 的限制数! echo 6553560 > /proc/sys/fs/file-max,修改一下最大文件数就行了,改成 6553560,然后重启 nginx 再次跑脚本的时候,就没有返回这些文件错误了,但是又返回了新的错误:Connection reset by peer*

 四、Connection reset by peer产生的原因与解决方案

  Connection reset reset 又称为 rst 复位。

  1、当 socket 连接异常关闭的时候,服务端会给客户端发送 RESET 信号,此时如果客户端正从套接字的输出流中读数据,就会返回Connection reset by peer。如下图所示,正在读取响应头

  2、当 socket 连接异常关闭的时候,服务端会给客户端发送 RESET 信号,此时如果客户端正往套接字的输出流中写数据,则会直接返回Connection reset

  3、出现 reset 有以下几种原因

    1、连接主动断开【三次握手发送 ack 报文的时候有重传机制,默认是 6 次。当重传次数超过 6 次的时候,连接会主动中断,然后发送 rst 报文】

    2、连接被主动丢弃【三次握手最后一个环节有 accept 队列,accept 队列溢出就会导致 tcp 连接被丢弃,然后发送 rst 报文】

  4、针对以上这两种问题,我们可以降低重传次数

    net.ipv4.tcp_syn_retries

    可以增加 accept 队列与 linux 系统队列

    net.core.netdev_max_backlog net.core.somaxconn

    关闭 rst 报文的发送,提高连接率

    net.ipv4.tcp_abort_on_overflow = 0

    在队列溢出的时候,绕过 syn 队列

    net.ipv4.tcp_syncookies = 1

3、数据长度不一致。发送方发送的数据大于接收方的尺寸,就会导致报文被丢弃,连接中断 Nginx 对响应头和响应体有配置缓冲区proxy_buffer_size,可以适当优化这个值

 或者优化 tcp 的内核参数net.ipv4.tcp_window_scaling = 1,这个值是缓冲区的滑动窗口,可以针对收发的尺寸做自适应

 五、总结

  优化的思路就是两条,保证足够的连接队列,保证足够的缓冲空间!

posted @ 2022-06-14 22:17  测试-知秋  阅读(596)  评论(0)    收藏  举报