Nginx性能优化-TCP篇
性能优化方法论
- 软件层面提升硬件使用率
- 增大CPU的利用率
- 增大内存的利用率
- 增大硬盘IO的利用率
- 增大网络带宽的利用率
- 提升硬件
- 网卡:万兆网卡
- 硬盘:固体硬盘,关注IOPS和BPS指标
- CPU:更快主频,更多核心,更大缓存,更优架构
- 内存:更快访问速度
- 超出硬件性能上限后使用DNS
TCP基本知识
三次握手和四次挥手
Tcp Fast Open
起到tcp加快通信的作用
-
net.ipv4.tcp_fastopen 系统开启TFO功能
- 0:关闭
- 1:作为客户端时
- 2:作为服务端时
- 3:无论客户端或服务端,都开启TFO
-
Tcp Fast Open nginx配置,指定TFO连接队列长度
滑动窗口
- 用于限制连接的网速,解决报文乱序和可靠传输问题
- Nginx中limit_rate等限速指令皆依赖它实现
- 由操作系统内核实现
- 连接两端各有发送窗口(用于发送内容)和接收窗口(用于接收内容)
nginx超时指令和滑动窗口
- 两次读操作间的超时
- 两次写操作间的超时
- 兼具两次读写操作间的超时
缓冲区
- 读缓存最小值、默认值、最大值、单位字节,覆盖net.core.rmem_max
- 写缓存最小值、默认值、最大值、单位字节,覆盖net.core.wmem_max
- 系统无内存压力,启动压力模式阈值、最大值,单位为页的数量
- 开启自动调整缓存模式
- 调整接收窗口与应用缓存
吞吐量=窗口/时延
BDP=带宽*时延
Nagle算法
作用:
1、避免一个连接上同时存在大量小报文:最多只存在一个小报文,合并多个小报文一起发送
2、提高带宽利用率
- Nagle算法在Nginx配置
- Nginx避免发送小报文配置
CORK算法
仅针对sendfile on开启时有效,完全禁止小报文的发送,提升网络效率
拥塞窗口
什么是拥塞窗口?发送方主动限制流量
什么是通告窗口?接收方限制流量
实际流量:拥塞窗口与通告窗口的最小值
拥塞处理:
-
慢启动
- 指数扩展拥塞窗口(cwnd为拥塞窗口大小)
- 每收到1个ACK,cwnd=cwnd+1
- 每过一个RTT,cwnd=cwnd*2
- 指数扩展拥塞窗口(cwnd为拥塞窗口大小)
-
拥塞避免
- 线性扩展拥塞窗口
- 每收到1个ACK,cwnd=cwnd+1/cwnd
- 每过一个RTT,窗口加1
- 线性扩展拥塞窗口
-
拥塞发送
- 急速降低拥塞窗口
- RTO超时,threshold=cwnd/2,cwnd=1
- Fast Retransmit ,收到3个duplicate ACK,cwnd=cwnd/2,threshold=cwnd
- 急速降低拥塞窗口
-
快速恢复
- 当Fast Retransmit出现时,cwnd调整为threshold+3*MSS
RTT(Round Trip Time)由物理链路传输时间+末端处理时间+路由器排队处理时间组成。
RTO(Retransmission Time Out)正确的重传之前的丢包
KeepAlive功能
tcp的keepalive和http的keepalive作用是不同的,http是为了复用,tcp则为了尽快释放。
tcp keepalive应用场景:检测实际断掉的连接和用于维持与客户端间防火墙有活跃网络包
linux系统的tcp keepalive:
- 发送心跳周期
- 探测包发送间隔
- 探测包重试次数
Nginx的tcp keepalive:
- so_keepalive=30m::10
- Keepidlea,keepintvl,keepcnt
time_wait状态
被动关闭连接
查看连接状态,State字段
- 存在大量CLOSE_WAIT状态:应用进程没有及时响应对端关闭连接
- 存在大量LAST_ACK状态:等待接收主动关闭端操作系统发来的针对FIN的ACK报文
主动关闭连接
fin_wait1状态和fin_wait2状态
- fin_wait1状态,发送FIN报文的重试次数,0相当于8
- fin_wait2状态,保持在FIN_WAIT_2状态的时间
time_wait状态有什么用?
time_wait存在的2个原因:
- 可靠地终止TCP连接
- 保证让迟来的TCP报文段有足够的时间被识别并丢弃
MSL(Maximum Segment Lifetime)报文最大生存时间,tcp报文生存周期1MSL,2MSL是为了确保网络上的tcp报文已经无了。所以维持TIME_WAIT状态的时长是2MSL,保证至少一次报文的往返时间内端口是不可复用。
time_wait优化
- 开启后,作为客户端时新连接可以使用仍然处于time_wait状态端口
- 由于timestamp的存在,操作系统可以拒绝迟到的报文
- 开启后,同时作为客户端和服务器都可以使用time_wait状态的端口,不安全,无法避免报文延迟、重复等给新连接造成混乱
- Time_wait状态连接的最大数量,超出后直接关闭连接
lingering_close延迟关闭
意义:当Nginx处理完成调用close关闭连接后,若接收缓冲区仍然收到客户端发来的内容,则服务器会向客户端发送RST包关闭连接,导致客户端由于收到RST而忽略了http response
Nginx配置:
- off 关闭功能
- on由Nginx判断,当用户请求未接收完(根据chunk或者Content-Length头部等)时启用功能,否则及时关闭连接
- always无条件启用功能
- 当功能启用时,最长的读取用户请求内容的时长,达到后立刻关闭连接
- 当功能启用时,检测客户端是否仍然请求内容到达,若超时后仍没有数据达到,则立刻关闭连接
RST代替正常四次挥手关闭连接
- 当读、写超时指令生效引发连接关闭时产生的异常,通过发送RST立刻释放端口、内存等资源来关闭连接
SYN攻击
什么是SYN攻击:攻击者短时间伪造不同IP地址的SYN报文,快速占满backlog队列,使服务器不能为正常用户服务
对SYN攻击防御的内核参数配置
- 接收自网卡,但未被内核协议栈处理的报文队列长度
- backlog队列长度,nginx配置
- SYN_RCVD状态连接的最大个数(半连接)
- 超出处理能力时,对新来的SYN直接回包RST,丢弃连接
- 当SYN队列满后,新的SYN不进入队列,计算出cookie再以SYN+ACK中的序列号返回客户端,正常客户端发报文时,服务器根据报文中携带的cookie重新恢复连接
- 由于cookie占用序列号空间,导致此时所有TCP可选功能失效,例如扩充窗口、时间戳等
文件句柄数
linux系统一切皆文件,并发的时候文件句柄数有上限
系统全局
- 操作系统可使用的最大句柄数
查看命令:sysctl -a|grep file-max
- 使用fs.file-nr可以查看当前已分配、正在使用、上限
查看命令:sysctl -a|grep file-nr
用户级别
进程级别
- nginx配置文件
相关配置
- 客户端 主动建立连接时,发SYN的重试次数
- 客户端 建立连接时的本地端口可用范围
- 主动建立连接时应用层超时时间
- 服务端 SYN_RCVD状态连接的最大个数(半连接)
- 服务端 被动建立连接时,发SYN/ACK的重试次数
- 接收自网卡,但未被内核协议栈处理的报文队列长度
- backlog队列长度,nginx配置
- ACCEPT队列已完成握手
- 超出处理能力时,对新来的SYN直接回包RST,丢弃连接
- 当SYN队列满后,新的SYN不进入队列,计算出cookie再以SYN+ACK中的序列号返回客户端,正常客户端发报文时,服务器根据报文中携带的cookie重新恢复连接
- 由于cookie占用序列号空间,导致此时所有TCP可选功能失效,例如扩充窗口、时间戳等
- 设置worker进程最大连接数量
-
net.ipv4.tcp_fastopen 系统开启TFO功能
- 0:关闭
- 1:作为客户端时
- 2:作为服务端时
- 3:无论客户端或服务端,都开启TFO
-
Tcp Fast Open nginx配置,指定TFO连接队列长度
- 两次读操作间的超时
- 两次写操作间的超时
- 兼具两次读写操作间的超时
- 限制重传次数-丢包重传达到上限后,更新路由缓存
- 限制重传次数-丢包重传达到上限后,关闭TCP连接
- Nagle算法在Nginx配置
- Nginx避免发送小报文配置
- 完全禁止小报文的发送
- 发送心跳周期
- 探测包发送间隔
- 探测包重试次数
- fin_wait1状态,发送FIN报文的重试次数,0相当于8
- fin_wait2状态,保持在FIN_WAIT_2状态的时间
- 开启后,作为客户端时新连接可以使用仍然处于time_wait状态端口
- 由于timestamp的存在,操作系统可以拒绝迟到的报文
- 开启后,同时作为客户端和服务器都可以使用time_wait状态的端口,不安全,无法避免报文延迟、重复等给新连接造成混乱
- Time_wait状态连接的最大数量,超出后直接关闭连接
- off 关闭功能
- on由Nginx判断,当用户请求未接收完(根据chunk或者Content-Length头部等)时启用功能,否则及时关闭连接
- always无条件启用功能
- 当功能启用时,最长的读取用户请求内容的时长,达到后立刻关闭连接
- 当功能启用时,检测客户端是否仍然请求内容到达,若超时后仍没有数据达到,则立刻关闭连接
- 当读写超时指令生效引发连接关闭时,通过发送RST立刻释放端口、内存等资源来关闭连接
__EOF__

本文链接:https://www.cnblogs.com/rxg456/p/16220187.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?