Linux内核参数调优实战:生产环境性能翻倍
上周线上服务扛不住流量,运维群里一顿排查,最后发现是内核参数没调。
默认配置跑个开发环境还行,生产环境就是在给自己挖坑。
把这次调优过程记录一下,都是踩过的坑。
背景
我们有台服务器,配置不差:
- 32核CPU
- 64G内存
- 万兆网卡
但是一到高峰期,CPU才30%,连接数就上不去了,大量请求超时。
看了一圈监控,发现是网络瓶颈,但网卡带宽明明还有余量。
问题定位
现象
# 查看连接状态
ss -s
Total: 52341
TCP: 48234 (estab 12000, closed 35000, orphaned 0, timewait 34500)
# 发现大量TIME_WAIT
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn
34523 TIME-WAIT
12034 ESTAB
1234 SYN-RECV
423 LISTEN
3万多个TIME_WAIT,正常吗?
短连接场景下其实很常见,但这么多确实有问题。
根因分析
# 查看当前内核参数
sysctl net.ipv4.tcp_max_tw_buckets
# 输出:net.ipv4.tcp_max_tw_buckets = 180000
sysctl net.core.somaxconn
# 输出:net.core.somaxconn = 128
sysctl net.ipv4.tcp_max_syn_backlog
# 输出:net.ipv4.tcp_max_syn_backlog = 1024
问题找到了:
somaxconn才128,这是监听队列的最大长度tcp_max_syn_backlog才1024,SYN队列太小
高并发下,新连接进来排队都排不下,直接被丢弃了。
调优方案
一、网络连接相关
# /etc/sysctl.conf
# 1. 监听队列最大长度(默认128太小)
net.core.somaxconn = 65535
# 2. SYN队列长度
net.ipv4.tcp_max_syn_backlog = 65535
# 3. 允许的最大跟踪连接条目
net.netfilter.nf_conntrack_max = 1000000
# 4. TIME_WAIT状态的socket数量(按需调整)
net.ipv4.tcp_max_tw_buckets = 200000
# 5. TIME_WAIT复用(仅限客户端发起连接时)
net.ipv4.tcp_tw_reuse = 1
# 6. 开启SYN cookies防护
net.ipv4.tcp_syncookies = 1
# 7. 减少FIN_WAIT2状态时间
net.ipv4.tcp_fin_timeout = 30
二、TCP缓冲区相关
# 接收缓冲区(最小、默认、最大)单位字节
net.ipv4.tcp_rmem = 4096 87380 16777216
# 发送缓冲区
net.ipv4.tcp_wmem = 4096 65536 16777216
# 系统级别的内存页面分配
net.ipv4.tcp_mem = 786432 1048576 1572864
# 单个socket最大缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
三、文件描述符相关
# 系统级最大文件描述符
fs.file-max = 1000000
# 单进程最大文件描述符(需要配合ulimit)
# 在 /etc/security/limits.conf 中设置:
# * soft nofile 1000000
# * hard nofile 1000000
四、应用生效
# 临时生效
sysctl -p
# 验证
sysctl net.core.somaxconn
# 输出:net.core.somaxconn = 65535
调优前后对比
压测数据
用wrk压测同一个接口:
wrk -t12 -c1000 -d60s http://localhost:8080/api/test
调优前:
Requests/sec: 8234.56
Latency: avg 234ms, max 3.2s
Socket errors: connect 3421, read 234, write 0, timeout 523
调优后:
Requests/sec: 23456.78
Latency: avg 42ms, max 234ms
Socket errors: connect 0, read 0, write 0, timeout 0
QPS从8000提升到23000,延迟从234ms降到42ms,错误归零。
生产环境表现
高峰期同样流量:
- CPU使用率:从30%提升到65%(资源用起来了)
- 连接错误率:从5%降到0.01%
- P99延迟:从800ms降到120ms
常见场景参数模板
场景一:高并发Web服务
# 适合Nginx、Tomcat等Web服务器
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 3
# Nginx还需要改配置
# worker_connections 65535;
# 并且在listen后加 backlog=65535
场景二:数据库服务器
# 适合MySQL、PostgreSQL等
# 内存相关(根据实际内存调整)
vm.swappiness = 10
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
# 文件系统
fs.file-max = 1000000
fs.aio-max-nr = 1048576
# 网络(数据库通常连接数不会太高但要稳定)
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
场景三:代理/网关服务
# 适合Nginx反向代理、API网关
# 代理需要大量连接,前端连接+后端连接
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 端口范围要大(代理会用很多端口连后端)
net.ipv4.ip_local_port_range = 1024 65535
# TIME_WAIT复用很重要
net.ipv4.tcp_tw_reuse = 1
# 连接跟踪表要大
net.netfilter.nf_conntrack_max = 2000000
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
一些坑
坑1:改了不生效
# 检查是否真的改了
sysctl -a | grep somaxconn
# 如果是容器环境,宿主机和容器的参数是隔离的
# 部分参数需要在宿主机改
坑2:Nginx的backlog
改了系统参数,Nginx也要配合改:
server {
listen 80 backlog=65535;
# ...
}
不然Nginx用的还是默认值511。
坑3:改了参数服务起不来
# 有些参数相互依赖,比如
net.core.netdev_max_backlog = 65535
# 要配合网卡驱动支持,不然可能有问题
建议一个个改,改完验证,别一次改一堆。
坑4:容器环境
Docker/K8s环境下:
- 大部分网络参数要在宿主机改
fs.file-max在容器里可能改不了- 需要用
--sysctl参数或者securityContext
# K8s Pod配置
spec:
containers:
- name: app
securityContext:
sysctls:
- name: net.core.somaxconn
value: "65535"
监控建议
调完参数不是结束,要持续监控:
# 连接状态分布
ss -ant | awk '{print $1}' | sort | uniq -c
# 丢包情况
netstat -s | grep -E "dropped|overflow"
# 连接跟踪表使用情况
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
写个脚本定期采集,出问题才知道往哪查。
异地运维小技巧
我们有几台服务器在异地机房,调参数的时候需要远程操作。
之前用跳板机,现在用星空组网把几台服务器组到一个虚拟网络里,直接SSH就能连,调参数方便多了。
总结
Linux内核参数调优核心就几个方向:
| 方向 | 关键参数 | 常见问题 |
|---|---|---|
| 监听队列 | somaxconn, tcp_max_syn_backlog | 高并发连接失败 |
| TIME_WAIT | tcp_tw_reuse, tcp_fin_timeout | 端口耗尽 |
| 缓冲区 | tcp_rmem, tcp_wmem | 大文件传输慢 |
| 连接跟踪 | nf_conntrack_max | 防火墙导致丢包 |
| 文件描述符 | file-max, nofile | too many open files |
记住几个原则:
- 先定位问题再调参数,别瞎调
- 改完要验证,压测或者灰度
- 留好回滚方案
- 持续监控,别调完就忘了
有内核调优经验的欢迎评论区交流~

浙公网安备 33010602011771号