内核参数调优(sysctl + limits)
场景
高并发服务报 Too many open files、Cannot assign requested address,或者连接队列溢出。
前置条件
- 知道是「文件句柄」还是「网络参数」的问题
- 改动前记下原值(
sysctl -a > /tmp/sysctl.bak) - 生产上先小范围验证
配置
cat >/etc/sysctl.d/99-ops.conf <<'EOF'
# 文件句柄
fs.file-max = 2097152
fs.nr_open = 2097152
# 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TIME_WAIT 复用
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# 端口范围
net.ipv4.ip_local_port_range = 10240 65000
# 内存
vm.swappiness = 10
vm.max_map_count = 262144
EOF
sysctl --system
进程级句柄(systemd 服务):
[Service]
LimitNOFILE=65535
用户级(/etc/security/limits.conf):
* soft nofile 65535
* hard nofile 65535
验证
sysctl fs.file-max net.core.somaxconn vm.swappiness
ulimit -n
cat /proc/1/limits | grep "open files"
回滚
rm /etc/sysctl.d/99-ops.conf
sysctl --system
坑
- 只改
/etc/sysctl.conf不生效,现代发行版读/etc/sysctl.d/*.conf。 ulimit -n改的是当前 shell,服务要改 systemd 的LimitNOFILE。tcp_tw_reuse只对出连接有效,入连接还是会有 TIME_WAIT。somaxconn调大后,应用层的 backlog 也要同步调。swappiness=0不等于禁用 swap,要禁用得swapoff。- 容器里改内核参数会报只读,得在宿主机改。