Linux 内核参数调优
大约 10 分钟约 2945 字
Linux 内核参数调优
简介
Linux 内核提供了数百个可调参数,通过 /proc/sys 虚拟文件系统和 sysctl 命令可以动态查看和修改这些参数。合理的内核参数调优可以显著提升系统的网络吞吐量、文件系统性能、内存管理效率和安全性。
内核参数调优是 Linux 性能优化的重要环节,但也是一个需要谨慎操作的过程。不当的参数修改可能导致系统不稳定甚至无法启动。本文将按照网络参数、内存参数、文件系统参数、安全参数等维度,系统性地介绍内核参数的调优方法和最佳实践。
调优原则
内核参数调优应遵循以下原则:先测量再优化、每次只改一个参数、在测试环境验证后再应用到生产环境、所有修改必须持久化到配置文件中。
sysctl 命令详解
基本用法
# 查看当前所有内核参数
sysctl -a
# 查看指定参数
sysctl net.ipv4.tcp_max_syn_backlog
# 通过 /proc/sys 查看(路径中 . 替换为 /)
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
# 临时修改参数(立即生效,重启失效)
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# 通过 /proc/sys 临时修改
echo 65535 > /proc/sys/net/ipv4/tcp_max_syn_backlog
# 从配置文件加载参数
sysctl -p /etc/sysctl.d/99-tuning.conf
# 加载所有配置文件
sysctl --system参数查看技巧
# 查看所有网络相关参数
sysctl -a | grep net.ipv4
# 查看所有文件系统相关参数
sysctl -a | grep fs.
# 查看所有内存相关参数
sysctl -a | grep vm.
# 查看参数是否可修改
sysctl -N net.ipv4.tcp_max_syn_backlog
# 查看参数说明
man 7 tcp # 查看 TCP 相关参数说明网络参数调优
TCP 连接优化
# /etc/sysctl.d/99-network.conf
# ========== TCP 队列优化 ==========
# 监听队列最大长度(SYN 队列 + Accept 队列)
# 高并发服务器建议调大,默认 128
net.core.somaxconn = 65535
# SYN 队列长度(半连接队列)
# 防止 SYN Flood 攻击,默认 128
net.ipv4.tcp_max_syn_backlog = 65535
# TIME_WAIT 状态连接的最大数量
# 默认与 somaxconn 相同
net.ipv4.tcp_max_tw_buckets = 65535
# ========== TCP 连接复用 ==========
# 允许将 TIME_WAIT 连接复用为新的连接
# 适用于客户端(主动关闭连接的一方)
net.ipv4.tcp_tw_reuse = 1
# FIN_WAIT_2 超时时间(秒)
# 默认 60 秒,调小可加速连接回收
net.ipv4.tcp_fin_timeout = 15
# ========== TCP 心跳与保活 ==========
# TCP KeepAlive 心跳间隔(秒)
# 默认 7200 秒(2 小时),生产环境建议调小
net.ipv4.tcp_keepalive_time = 600
# TCP KeepAlive 心跳重试间隔(秒)
net.ipv4.tcp_keepalive_intvl = 30
# TCP KeepAlive 心跳重试次数
# 总超时 = keepalive_time + keepalive_intvl * keepalive_probes
net.ipv4.tcp_keepalive_probes = 5
# ========== TCP 缓冲区优化 ==========
# 最大接收缓冲区(字节)
# 默认 212992(约 208KB),高吞吐场景建议调大
net.core.rmem_max = 16777216
# 最大发送缓冲区(字节)
net.core.wmem_max = 16777216
# TCP 接收缓冲区(min / default / max)
# 动态调整范围,单位字节
net.ipv4.tcp_rmem = 4096 87380 16777216
# TCP 发送缓冲区(min / default / max)
net.ipv4.tcp_wmem = 4096 65536 16777216
# 默认接收缓冲区大小
net.core.rmem_default = 262144
# 默认发送缓冲区大小
net.core.wmem_default = 262144
# ========== 端口范围 ==========
# 本地可用端口范围(客户端连接源端口)
# 默认 32768-60999,高并发场景建议扩大
net.ipv4.ip_local_port_range = 1024 65535
# ========== SYN 防护 ==========
# 开启 SYN Cookie 防护(防 SYN Flood 攻击)
# 当 SYN 队列满时,使用加密 Cookie 代替 SYN 队列
net.ipv4.tcp_syncookies = 1
# SYN+ACK 重试次数
# 默认 5 次,调小可减少 SYN Flood 时的资源消耗
net.ipv4.tcp_synack_retries = 2
# SYN 重试次数
# 默认 6 次,调小可加速连接失败检测
net.ipv4.tcp_syn_retries = 2
# ========== 网络接口优化 ==========
# 网络设备接收队列长度
# 多核服务器建议调大
net.core.netdev_max_backlog = 65535
# 最大 socket 连接跟踪数
net.netfilter.nf_conntrack_max = 1048576
# ========== TCP 拥塞控制 ==========
# TCP 拥塞控制算法
# 可选:cubic(默认), bbr, reno, westwood
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbrTCP 参数关系图
客户端 服务端
| |
|-- SYN ---------------> | (进入 SYN 队列,长度 tcp_max_syn_backlog)
| <-- SYN+ACK ---------- |
|-- ACK ---------------> | (从 SYN 队列移入 Accept 队列,长度 somaxconn)
| |
|-- 数据传输 ----------> |
| <-- 数据传输 ---------- |
| |
|-- FIN ---------------> | (进入 FIN_WAIT_2,超时 fin_timeout)
| <-- FIN -------------- |
| <-- ACK -------------- | (进入 TIME_WAIT,上限 tcp_max_tw_buckets)内存与文件系统参数
内存管理参数
# /etc/sysctl.d/99-memory.conf
# ========== Swap 管理 ==========
# Swap 使用倾向(0-100)
# 0 = 尽量不用 swap,100 = 积极使用 swap
# 数据库服务器建议设为 1-10
vm.swappiness = 10
# 内存超分配策略
# 0 = 不允许超分配(严格模式)
# 1 = 允许适度超分配(默认)
# 2 = 总是允许超分配
# Redis 等需要大量内存的应用建议设为 1
vm.overcommit_memory = 1
# ========== 内存映射 ==========
# 最大内存映射区域数
# Elasticsearch、MongoDB 等需要调大
# 默认 65530
vm.max_map_count = 262144
# 脏页比例(占系统总内存的百分比)
# 达到此比例时触发同步写入磁盘
vm.dirty_ratio = 15
# 后台写入脏页比例
# 达到此比例时 pdflush/kworker 开始后台写入
vm.dirty_background_ratio = 5
# ========== 内存回收 ==========
# 最小保留的空闲内存(KB)
vm.min_free_kbytes = 65536
# OOM Killer 权重
# -1000 = 永远不被杀,1000 = 优先被杀
# 保护重要进程文件系统参数
# /etc/sysctl.d/99-fs.conf
# ========== 文件描述符 ==========
# 系统级最大文件描述符数
# 默认约 10 万,高并发服务器建议调大
fs.file-max = 1048576
# inotify 监控文件数上限
# 开发工具(IDE、热重载)需要调大
fs.inotify.max_user_watches = 524288
# inotify 实例上限
fs.inotify.max_user_instances = 512
# ========== 共享内存 ==========
# 最大共享内存段(字节)
# PostgreSQL、Oracle 等数据库需要调大
kernel.shmmax = 68719476736
# 共享内存页总数
kernel.shmall = 4294967296
# 最大共享内存段数
kernel.shmmni = 4096
# ========== 文件系统 ==========
# 文件句柄回收延迟
fs.file-handle-cache-size = 10000文件描述符限制
# 查看当前文件描述符限制
ulimit -n # 当前用户 soft limit
ulimit -Hn # 当前用户 hard limit
cat /proc/sys/fs/file-nr # 系统级(已用/未用/最大)
# /etc/security/limits.conf
# * = 所有用户
* soft nofile 65535 # soft limit(用户可调到此值)
* hard nofile 65535 # hard limit(root 可调)
* soft nproc 65535 # 最大进程数
* hard nproc 65535
# 为特定用户设置
root soft nofile 65535
root hard nofile 65535
mysql soft nofile 65535
mysql hard nofile 65535
# /etc/security/limits.d/20-nproc.conf
# 解决 fork: resource temporarily unavailable
* soft nproc 65535
root soft nproc unlimited
# systemd 服务级别限制
# 在 .service 文件中设置
[Service]
LimitNOFILE=65535
LimitNPROC=65535安全相关参数
# /etc/sysctl.d/99-security.conf
# ========== IP 转发与源地址验证 ==========
# 禁用 IP 转发(非路由器)
net.ipv4.ip_forward = 0
# 启用反向路径过滤(防止 IP 欺骗)
# 0 = 不验证,1 = 严格验证,2 = 宽松验证
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 禁用 ICMP 重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# 禁用发送 ICMP 重定向
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# ========== SYN Flood 防护 ==========
# 开启 SYN Cookie
net.ipv4.tcp_syncookies = 1
# ========== 内核安全 ==========
# 禁用内核转储
kernel.core_pattern = |/bin/false
# 限制 core 文件大小
fs.suid_dumpable = 0
# 地址空间随机化(ASLR)
kernel.randomize_va_space = 2
# 禁用 SysRq 键
kernel.sysrq = 0
# ========== 网络安全 ==========
# 忽略 ICMP 广播
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 忽略 ICMP 错误响应
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 禁止接收源路由包
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# 启用 execshield(缓冲区溢出保护)
kernel.exec-shield = 1不同场景的调优方案
Web 服务器(Nginx/Apache)
# /etc/sysctl.d/99-webserver.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_fin_timeout = 15
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
fs.file-max = 1048576数据库服务器(MySQL/PostgreSQL)
# /etc/sysctl.d/99-database.conf
vm.swappiness = 1
vm.overcommit_memory = 1
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
fs.file-max = 1048576容器宿主机(Docker/Kubernetes)
# /etc/sysctl.d/99-container.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.all.forwarding = 1
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 512
vm.max_map_count = 262144
net.netfilter.nf_conntrack_max = 1048576参数持久化
配置文件组织
# /etc/sysctl.d/ 目录下的配置文件(推荐)
# 文件名格式:NN-name.conf(NN 为数字,控制加载顺序)
/etc/sysctl.d/99-network.conf
/etc/sysctl.d/99-memory.conf
/etc/sysctl.d/99-security.conf
# 或使用传统配置文件(兼容)
/etc/sysctl.conf
# 加载所有配置文件
sysctl --system
# 加载指定配置文件
sysctl -p /etc/sysctl.d/99-network.conf
# 查看所有已加载的配置
sysctl --system 2>&1 | grep "Applying"常见问题排查
参数修改后不生效
# 1. 确认参数已修改
sysctl net.ipv4.tcp_max_syn_backlog
# 2. 确认配置文件格式正确
sysctl -p /etc/sysctl.d/99-tuning.conf
# 3. 某些参数需要重启进程才能生效
# 例如 ulimit 修改后需要重启应用
# 4. 某些参数不可修改
sysctl -w net.ipv4.tcp_tw_reuse=2
# 可能报错:sysctl: setting key "net.ipv4.tcp_tw_reuse": Invalid argument文件描述符不够
# 查看进程打开的文件描述符数
ls /proc/<PID>/fd | wc -l
# 查看系统文件描述符使用情况
cat /proc/sys/fs/file-nr
# 错误信息:Too many open files
# 解决:
# 1. 调大 fs.file-max
# 2. 调大 ulimit -n
# 3. 检查应用是否有文件描述符泄漏内核参数监控与验证
参数生效验证
# 验证参数是否生效
sysctl -a | grep "net.ipv4.tcp_tw_reuse\|net.core.somaxconn\|vm.swappiness"
# 使用 sysctl -p 加载后立即检查
sysctl -p /etc/sysctl.d/99-network.conf && sysctl net.core.somaxconn
# 检查 TCP 连接状态分布(验证 TIME_WAIT 优化效果)
ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k, s[k]}'
# 输出示例:
# ESTAB 128
# TIME-WAIT 45
# LISTEN 5
# 查看当前 TCP 连接的队列情况
cat /proc/net/sockstat
# sockets: used 258
# TCP: inuse 128 orphan 0 tw 45 alloc 130 mem 15
# 查看半连接队列溢出次数(非 0 说明 tcp_max_syn_backlog 不够)
netstat -s | grep "SYNs to LISTEN"
# 12345 SYNs to LISTEN sockets dropped
# 查看 Accept 队列溢出次数
netstat -s | grep "listen queue"
# 0 times the listen queue of a socket overflowed系统资源监控
# 查看当前文件描述符使用情况
cat /proc/sys/fs/file-nr
# 1216 0 1048576
# 已打开 最大值
# 查看某个进程的文件描述符数
ls /proc/$(pgrep nginx | head -1)/fd | wc -l
# 查看内存使用和 Swap 情况
free -h
# total used free shared buff/cache available
# Mem: 15Gi 8.0Gi 2.0Gi 256Mi 5.0Gi 6.5Gi
# Swap: 4.0Gi 0B 4.0Gi
# 查看 Swap 使用详情
cat /proc/swaps
# Filename Type Size Used Priority
# /dev/dm-1 partition 4194300 0 -2
# 查看 OOM Killer 日志
dmesg | grep -i "oom"
journalctl -k | grep -i "oom"
# 查看 conntrack 表使用情况
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# 如果 count 接近 max,需要调大 nf_conntrack_maxTCP 性能监控脚本
#!/bin/bash
# tcp_monitor.sh — TCP 连接监控脚本
# 用法: ./tcp_monitor.sh [interval]
INTERVAL=${1:-5}
echo "=== TCP 连接监控 (间隔 ${INTERVAL}s) ==="
echo "按 Ctrl+C 退出"
echo ""
while true; do
echo "--- $(date '+%Y-%m-%d %H:%M:%S') ---"
# 连接状态统计
ss -ant | awk 'NR>1 {++s[$1]} END {
printf "ESTAB: %-6d TIME-WAIT: %-6d CLOSE-WAIT: %-6d LISTEN: %-6d\n",
s["ESTAB"]+0, s["TIME-WAIT"]+0, s["CLOSE-WAIT"]+0, s["LISTEN"]+0
}'
# 队列溢出检查
SYN_DROPS=$(netstat -s 2>/dev/null | grep "SYNs to LISTEN" | awk '{print $1}')
ACCEPT_DROPS=$(netstat -s 2>/dev/null | grep "listen queue.*overflow" | awk '{print $1}')
printf "SYN Drops: %-6s Accept Drops: %s\n" "$SYN_DROPS" "$ACCEPT_DROPS"
# 文件描述符
FD_INFO=$(cat /proc/sys/fs/file-nr)
printf "FD: %s\n" "$FD_INFO"
# Conntrack
CT_COUNT=$(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null || echo "N/A")
CT_MAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null || echo "N/A")
printf "Conntrack: %s / %s\n" "$CT_COUNT" "$CT_MAX"
echo ""
sleep "$INTERVAL"
done调优最佳实践
调优流程
1. 建立基线 — 记录调优前的系统指标(QPS、延迟、错误率)
2. 确定瓶颈 — 使用 top/iotop/netstat/ss 定位瓶颈
3. 修改参数 — 每次只改一个参数
4. 压测验证 — 使用 ab/wrkJMeter 进行压力测试
5. 对比结果 — 与基线对比,确认是否有改善
6. 持久化配置 — 将有效的参数写入 /etc/sysctl.d/
7. 记录文档 — 记录修改的参数、原因和效果常见调优误区
# 误区 1:盲目调大所有参数
# 不是所有参数都越大越好,例如:
# tcp_max_tw_buckets 过大可能导致 TIME_WAIT 积压
# vm.min_free_kbytes 过大会浪费可用内存
# 误区 2:忽略应用程序本身的问题
# 很多性能问题不是内核参数的问题,而是:
# - 数据库慢查询
# - 内存泄漏
# - 连接池配置不当
# - 代码逻辑问题
# 误区 3:在低负载环境下调优
# 调优应基于真实或接近真实的负载场景
# 低负载下的测试结果没有参考价值
# 误区 4:直接复制他人的调优参数
# 不同业务场景、硬件配置和网络环境需要的参数不同
# 必须根据自身场景测试验证常用压测工具
# 1. Apache Bench — 简单的 HTTP 压测
ab -n 10000 -c 200 http://localhost:8080/api/test
# -n 总请求数 -c 并发数
# 2. wrk — 更精确的 HTTP 压测
wrk -t4 -c200 -d30s http://localhost:8080/api/test
# -t 线程数 -c 连接数 -d 持续时间
# 3. sysbench — 综合性能测试
sysbench cpu run # CPU 测试
sysbench memory run # 内存测试
sysbench fileio --file-test-mode=rndrw run # 磁盘 IO 测试
# 4. TCP 连接压测(验证 somaxconn 和 tcp_max_syn_backlog)
# 使用 webbench 或自定义脚本