深色模式
内核参数导致的故障
摘要:文件句柄不够、端口范围太小、backlog 太短是三类最常见却最难想到原因的故障。本文先讲清 sysctl 全局参数与 ulimit 进程限制的层级关系,再给出逐项核对命令与安全修改方式。
适用环境
bash
sysctl --version
cat /etc/os-release | head -2
systemctl --version | head -11
2
3
2
3
排障步骤
第 1 步:分清两个层级的限制
- 系统级:
/proc/sys/...(sysctl),如fs.file-max - 进程级:
ulimit,如open files
bash
sysctl fs.file-max fs.file-nr
ulimit -Sn; ulimit -Hn
cat /proc/<PID>/limits | grep -i 'open files'1
2
3
2
3
第 2 步:文件句柄耗尽
bash
cat /proc/sys/fs/file-nr # 已用/未用/上限
cat /proc/sys/fs/file-max
ls /proc/<PID>/fd | wc -l1
2
3
2
3
systemd 服务的 limit 不看 limits.conf
由 systemd 管理的服务以 unit 中 LimitNOFILE 为准,/etc/security/limits.conf 对它无效。修改后需 systemctl daemon-reload 并重启服务。
第 3 步:临时端口范围耗尽
bash
cat /proc/sys/net/ipv4/ip_local_port_range
ss -ant state time-wait | wc -l1
2
2
高频短连接外访时,若临时端口被 TIME_WAIT 占满会报 Cannot assign requested address。
第 4 步:backlog 与半连接队列
bash
sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog
netstat -s 2>/dev/null | grep -iE 'overflow|dropped'1
2
2
第 5 步:安全修改内核参数
bash
# 临时生效(重启失效)
sysctl -w net.core.somaxconn=4096
# 持久化
cat > /etc/sysctl.d/99-tune.conf <<'EOF'
net.core.somaxconn = 4096
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 1000000
EOF
sysctl --system1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
sysctl -p 不会加载 sysctl.d
sysctl -p 默认只加载 /etc/sysctl.conf。放在 /etc/sysctl.d/*.conf 的文件必须用 sysctl --system 才会加载,否则重启后参数丢失。
第 6 步:确认容器内是否可修改
bash
sysctl -w net.core.somaxconn=4096 2>&1 | head -31
大部分网络类 sysctl 是宿主机全局的
容器默认共享宿主机网络命名空间相关参数,需 privileged 并放开对应 capability 才能修改,且会影响同节点所有容器。
验证
bash
sysctl net.core.somaxconn net.ipv4.ip_local_port_range fs.file-max
cat /proc/<PID>/limits | grep -i 'open files'
curl -sS -o /dev/null -w 'code=%{http_code}\n' http://127.0.0.1:8080/1
2
3
2
3
常见坑
照搬过时文档启用 tcp_tw_recycle
该参数已从较新内核移除,且在 NAT 环境下会造成连接被随机丢弃。旧教程中的这条配置必须剔除。
误把 file-max 当成单进程限制
fs.file-max 是整机上限,单进程仍受 ulimit -n 约束,两者都要调才有效。
修改后未验证是否真正生效
容器、systemd、PAM 三个层级可能层层覆盖,务必在目标进程里读 /proc/<PID>/limits 确认。
一次性批量套用网上的"内核优化模板"
大量未经理解的参数会带来未知副作用(如改动内存回收策略引发抖动)。应逐项按需修改并压测验证。