# 内核参数调优(sysctl + limits) ## 场景 高并发服务报 `Too many open files`、`Cannot assign requested address`,或者连接队列溢出。 ## 前置条件 - 知道是「文件句柄」还是「网络参数」的问题 - 改动前记下原值(`sysctl -a > /tmp/sysctl.bak`) - 生产上先小范围验证 ## 配置 ```bash 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 服务): ```ini [Service] LimitNOFILE=65535 ``` 用户级(`/etc/security/limits.conf`): ```text * soft nofile 65535 * hard nofile 65535 ``` ## 验证 ```bash sysctl fs.file-max net.core.somaxconn vm.swappiness ulimit -n cat /proc/1/limits | grep "open files" ``` ## 回滚 ```bash 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`。 - 容器里改内核参数会报只读,得在宿主机改。