高并发场景下内核默认参数的瓶颈
CentOS/Ubuntu默认的内核参数面向通用场景,当Web服务器并发连接数超过5000或QPS突破8000时,默认配置会成为瓶颈。常见的症状包括:TIME_WAIT状态连接堆积导致端口耗尽、SYN队列溢出导致连接被丢弃、文件描述符不足导致accept失败。
排查方式是通过/proc文件系统查看实时状态,确认瓶颈点后再调整对应参数,而非盲目套用网上的”万能优化配置”。
TCP连接相关参数调优
TCP参数是高并发Web服务器调优的核心。以下参数写在/etc/sysctl.d/99-webserver.conf中:
# TCP连接复用,允许将TIME_WAIT状态的连接重新用于新的TCP连接
net.ipv4.tcp_tw_reuse = 1
# 快速回收TIME_WAIT连接(仅在内网环境开启,NAT环境慎用)
net.ipv4.tcp_tw_recycle = 0
# TIME_WAIT状态连接的最大数量,默认262144
net.ipv4.tcp_max_tw_buckets = 5000
# SYN队列长度,默认1024,高并发建议8192以上
net.ipv4.tcp_max_syn_backlog = 8192
# accept队列长度,通过somaxconn控制
net.core.somaxconn = 8192
# SYN+ACK重试次数,默认5次约180秒,改为2次约30秒
net.ipv4.tcp_synack_retries = 2
# 开启SYN Cookies防止SYN Flood攻击
net.ipv4.tcp_syncookies = 1
# FIN-WAIT-2状态超时时间,默认60秒
net.ipv4.tcp_fin_timeout = 15
# keepalive探测间隔,默认7200秒
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
关于tcp_tw_recycle:这个参数在内核4.12以后已被移除。在NAT环境下开启会导致来自同一公网IP的不同客户端连接被错误丢弃。如果内核版本较旧且环境为纯内网,可以考虑开启,否则保持关闭。
文件描述符与连接数限制
每个TCP连接占用一个文件描述符。系统级限制通过fs.file-max控制,进程级限制通过nofile控制。两层限制都需要调整:
# 系统级文件描述符限制
fs.file-max = 1048576
# 网卡接收/发送队列长度
net.core.netdev_max_backlog = 16384
# 网卡接收ring buffer大小(需结合硬件支持范围调整)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
进程级限制在/etc/security/limits.conf中配置:
# nginx用户文件描述符限制
nginx soft nofile 655360
nginx hard nofile 655360
# 全局默认限制
* soft nofile 655360
* hard nofile 655360
对于systemd管理的服务,limits.conf不生效,需要在service文件中设置LimitNOFILE:
[Service]
LimitNOFILE=655360
LimitNPROC=655360
内存与TCP缓冲区调优
TCP读写缓冲区直接影响内存占用和吞吐性能。tcp_rmem和tcp_wmem三个值分别代表最小值、默认值和最大值:
# TCP读缓冲区(min default max)
net.ipv4.tcp_rmem = 4096 87380 16777216
# TCP写缓冲区(min default max)
net.ipv4.tcp_wmem = 4096 65536 16777216
# TCP内存使用上限(页为单位,1页=4KB)
net.ipv4.tcp_mem = 786432 1048576 1572864
缓冲区不是越大越好。16MB的读写缓冲区适合大文件传输场景,对于API服务器这种小包高频场景,4MB足矣。过大的缓冲区会导致内存浪费,在C10K甚至C100K场景下可能触发OOM。
内核参数生效与验证
配置文件写好后,执行sysctl -p /etc/sysctl.d/99-webserver.conf使其生效。验证参数是否正确加载:
# 查看所有TCP相关参数
sysctl -a | grep net.ipv4.tcp
# 查看当前TCP连接状态分布
ss -s
# 查看各状态连接数
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
# 查看SYN队列溢出次数
nstat -az TcpExtListenOverflows TcpExtListenDrops
# 查看文件描述符使用情况
cat /proc/sys/fs/file-nr
TcpExtListenOverflows如果持续增长,说明accept队列溢出,需要增大somaxconn和应用的listen()backlog参数。这个计数器是累加值,需要间隔采样对比增量。
内核参数与Nginx配置的联动
内核参数调优需要与Nginx配置配合才能发挥效果。常见问题和对应方案:
- 内核somaxconn=8192但连接仍然溢出——Nginx默认backlog为511,需要在
nginx.conf中设置listen 80 backlog=8192; - 文件描述符限制已提高但仍报too many open files——检查worker_processes和worker_connections的乘积是否超过nofile限制,Nginx总连接数=worker_processes×worker_connections
- TIME_WAIT仍然偏高——在Nginx中开启keepalive减少连接建立/断开频率,upstream到后端的连接开启keepalive复用
# nginx.conf 关键配置
events {
worker_connections 16384;
use epoll;
}
http {
# 客户端keepalive
keepalive_timeout 65;
keepalive_requests 1000;
# upstream keepalive
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
}
}
参数调优的监控与回归
参数调整后需要持续监控,确认效果并防止回退。核心监控指标:
| 指标 | 采集方式 | 异常阈值 |
|---|---|---|
| TIME_WAIT连接数 | ss -ant | grep TIME-WAIT | wc -l |
超过tcp_max_tw_buckets的80% |
| SYN队列溢出速率 | nstat TcpExtListenOverflows |
每秒增量大于0 |
| 文件描述符使用率 | cat /proc/sys/fs/file-nr |
已分配数/file-max大于80% |
| established连接数 | ss -ant | grep ESTAB | wc -l |
接近worker_connections上限 |
建议将这些指标接入Prometheus+Grafana监控体系,设置告警阈值。内核参数调优不是一次性操作,业务流量变化后需要重新评估。每次修改只调整一组相关参数,观察24小时后再做下一轮调整,避免变量混淆。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-nei-he-can-shu-diao-you-shi-zhan-gao-bing-fa-web-fu/