查看原文
其他

Nginx高并发调优中常被忽略的参数

运维研习社 运维研习社 2022-11-05


在nginx或php-fpm优化的时候,经常会碰到一个参数:backlog


backlog是什么?


在nginx官方文档中定义如下:

在php-fpm中解释如下:


从上面的解释来看,就是定义了一个队列,并设置了队列长度,那么这个队列是做什么的,接着往下看


不管是nginx还是php-fpm中backlog配置的地方都是在listen指令的位置,为什么是在listen指令的位置配置,通过一张图来看下

我们知道,listen是用来创建一个监听,打开一个端口、文件描述符,用于等待客户端请求,上面这张图是TCP内核的请求过程


  • client发送SYN到server,将状态修改为SYN_SEND,如果server收到请求,则将状态修改为SYN_RCVD,并把该请求放到syns queue队列中

  • server回复SYN+ACK给client,如果client收到请求,则将状态修改为ESTABLISHED,并发送ACK给server

  • server收到ACK,将状态修改为ESTABLISHED,并把该请求从syns queue中放到accept queue


上面过程中的状态看着是不是很熟悉,我们通常在服务器上通过ss或netstat查看端口状态的时候,其实就是TCP连接状态


而syns queue和accept queue是由操作系统内核维护的两个队列

在操作系统中这两个队列分别由两个内核参数定义

就是上图中的net.core.somaxconn和net.ipv4.tcp_max_syn_backlog

这两个参数也是通常你看到的优化nginx文章中推荐要设置的两个参数,如上图,net.ipv4.tcp_max_syn_backlog参数决定了SYN_RECV状态队列也就是syns queue队列的长度,一般默认值为512或1024,根据服务器内存,可以通过/proc/sys/net/ipv4/tcp_max_syn_backlog查看,超过这个数量,系统将不再接受新的TCP连接请求,这里说明下,不再接受新的请求,但是不会发送reset等,而是对SYN包不再响应SYN/ACK包,通常只是丢弃SYN包,这种设计方法就比较优雅,不返回RST,客户端可以进行重试,在内核中同样也有参数配置,通过net.ipv4.tcp_syn_retries参数可以配置SYN重试次数,这样在队列腾出空闲位置时,客户端可以重新建立连接,而不是直接被reset


但是这个参数的生效和tcp_syncookies又有一定的联系,在linux的系统调用的man文档中

在syncookies启用的情况下,逻辑上没有最大值限制,这个设置被忽略,syncookies通常被开启,用于防止SYN Flood攻击


简单说一下syncookies,syncookies设计就是用来防止SYN Flood攻击的,它的原理是,在TCP服务器接收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值,这个cookie作为将要返回的SYN ACK包的初始序列号,当客户端返回一个ACK包时,根据包头信息计算cookie,与返回的确认序列号(初始序列号+1)进行对比,如果相同,则时一个正常连接,然后分配资源,建立连接


扯远了,接着说另外一个参数net.core.somaxconn,该参数决定了listen监听队列的大小,也就是accept queue队列的大小。在使用listen函数时,内核会根据传入的backlog参数与系统内参参数somaxcoon,取其中最小值作为backlog的值,这也就是上面为上面backlog参数配置在listen指令的位置了


这个参数在内核中通常默认128,可以通过 /proc/sys/net/core/somaxconn查看,接着通过简单测试测试backlog值的选择


首先是初始配置,内核是默认128,nginx默认511(这个在源码中可以查看),然后通过ss查看

下图是nginx源码中对backlog的定义

接着修改内核参数somaxconn为1024,再通过ss查看

查看nginx对应的Send-Q

从上面的结果来看确实是根据最小值来决定backlog的,所以你之前配置的内核参数,对于nginx来说,默认情况下,不管你设置多大,这个队列都是511,并没有达到优化的效果


那么对于nginx,对于php-fpm,backlog应该设置多大,是越大越好吗?下篇文章通过压测来看下backlog怎么设置合适


上面关于内核参数的更多内容可以通过linux内核官方手册查找https://www.kernel.org/doc/man-pages/

推荐阅读HTTP/3 初体验 Serverless是怎么“无”服务器工作的 Nginx域名解析流程,源码分析 



更多精彩内容请扫描下方二维码关注公众号


扫描二维码关注我们吧



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存