内核参数调优:sysctl 里值得改的十来个值
默认内核参数面向「通用场景」,对 Web 服务器来说偏保守。改几个值能明显提升并发能力——但也可能改出问题,所以要理解每个值在干什么。
一、先看当前值
sysctl -a # 全部(很多)
sysctl net.ipv4.tcp_syncookies
sysctl -a | grep -i "somaxconn"
# 临时修改(重启失效)
sudo sysctl -w net.core.somaxconn=65535
# 永久生效:写进 /etc/sysctl.d/
echo "net.core.somaxconn=65535" | sudo tee -a /etc/sysctl.d/99-baize.conf
sudo sysctl --system # 重新加载所有配置优先写
/etc/sysctl.d/99-xxx.conf,不要直接改/etc/sysctl.conf,分文件更好管理。
二、网络相关(Web 服务器重点)
# /etc/sysctl.d/99-baize.conf
# 1. 监听队列长度:高并发时默认 128 太小
net.core.somaxconn = 65535
# 2. 半连接队列:防 SYN flood,同时要够用
net.ipv4.tcp_max_syn_backlog = 65535
# 3. SYN cookies:防 SYN flood,一般建议开
net.ipv4.tcp_syncookies = 1
# 4. TIME_WAIT 复用:短连接多时必开
net.ipv4.tcp_tw_reuse = 1
# 5. TIME_WAIT 最大数量
net.ipv4.tcp_max_tw_buckets = 262144
# 6. 本地端口范围:作为客户端时可用端口(反代到后端会用)
net.ipv4.ip_local_port_range = 1024 65535
# 7. 启用窗口缩放,高延迟网络下提升吞吐
net.ipv4.tcp_window_scaling = 1
# 8. 自动调优接收/发送缓冲区
net.ipv4.tcp_moderate_rcvbuf = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 9. 拥塞控制算法:BBR 对长肥管道(高延迟高带宽)效果明显
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# 10. 开启转发(做网关/NAT 时才需要,普通 Web 服务器不用)
# net.ipv4.ip_forward = 1sudo sysctl --system
# 确认 BBR 生效
sysctl net.ipv4.tcp_congestion_control
lsmod | grep bbr关于 tcp_tw_recycle
这个值已经被内核移除,也不要再设。 它在 NAT 环境下会导致连接被随机丢弃,是个历史坑。网上老教程还在推荐,别信。
三、文件描述符
「too many open files」是高并发下的经典错误。
ulimit -n # 当前会话限制,默认常是 1024
ulimit -Hn # 硬限制
cat /proc/sys/fs/file-max # 系统全局上限
cat /proc/sys/fs/file-nr # 已用/空闲/上限# 系统级
fs.file-max = 1000000
fs.nr_open = 1000000用户级在 /etc/security/limits.conf:
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535systemd 服务的限制要在 unit 文件里单独设(limits.conf 对 systemd 服务不生效):
[Service]
LimitNOFILE=65535# 看某个进程的实际限制
cat /proc/<PID>/limits | grep "open files"四、内存与交换
# swappiness:值越小越倾向用物理内存
# 服务器(尤其是数据库)建议 1~10
vm.swappiness = 10
# 脏页写回阈值(占内存比例),写密集场景可调小让回写更平滑
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10
# 内存分配策略:Redis 等建议设 1(避免 overcommit 导致 fork 失败)
vm.overcommit_memory = 1
# 禁用 IPv6(仅在确认不用时)
# net.ipv6.conf.all.disable_ipv6 = 1五、安全相关
# 忽略 ICMP 广播,防 smurf 攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 不响应 ICMP 重定向(防路由劫持)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
# 开启反向路径过滤,防 IP 欺骗
net.ipv4.conf.all.rp_filter = 1
# 记录可疑包( martian packet,源地址不可能的包)
net.ipv4.conf.all.log_martians = 1六、验证效果
# 连接状态分布(看 TIME_WAIT 多不多)
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn
# 看监听队列有没有溢出
netstat -s | grep -i "listen"
# 或
ss -lnt
# Recv-Q / Send-Q 长期不为 0 说明有积压
# 压测(别对生产环境乱压)
# wrk -t4 -c100 -d30s http://127.0.0.1/七、风险提示
在改之前,请记住:
- 一次只改一个值,改完观察,别一次套用网上一整份「优化脚本」;
- 改完用
sysctl --system生效,重启验证一次; - 留好回滚方式:配置文件分文件放,出问题注释掉即可;
- 大部分参数只有高并发下才有区别。日访问几千的站点,默认值完全够用;
- 云厂商的镜像往往已做过基础优化,先看看再改。
# 备份当前配置,方便对比
sudo sysctl -a > /tmp/sysctl-before.conf八、一份保守的通用配置
# /etc/sysctl.d/99-baize.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
fs.file-max = 200000
vm.swappiness = 10
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.rp_filter = 1这份配置在各类 Web 服务器上都算安全,没有激进值。
调优的原则是按需。没有压测数据支撑的优化,本质上是在碰运气。
