avatar

Ryan's Blog

The first step is always the hardest.

  • 首页
  • 分类
  • 标签
  • 归档
  • 关于
  • 工具
Home Linux 内核与网络参数调优:sysctl、文件描述符、TCP 队列与高并发配置
文章

Linux 内核与网络参数调优:sysctl、文件描述符、TCP 队列与高并发配置

Posted 2022-10-17 Updated 3 days ago
By Ryan Chen
33~42 min read

前言

Linux 参数调优不是把网上的一组 sysctl.conf 复制到服务器上。真正有效的调优应该从业务场景出发,先发现瓶颈,再修改参数,最后通过压测和监控验证。

这篇文章围绕常见服务器场景,整理 Linux 内核与网络参数调优思路,重点包括:

  • sysctl 配置文件和生效方式;
  • 文件描述符、进程数、端口范围;
  • TCP 连接队列、SYN Flood、TIME_WAIT;
  • 多网卡、ARP、rp_filter;
  • swappiness、vm.max_map_count;
  • 不建议盲目套用的历史参数;
  • 调优前后的验证清单。

如果需要通过压测验证调优效果,可以参考:SysBench 压测实践:CPU、内存、FileIO 与 MySQL OLTP 基准测试指南。如果需要排查命令速查,可以参考:Linux 常用命令速查:磁盘、日志、进程、网络、Docker 与文件排查实践。

调优前先确认场景

不同场景的参数目标不同:

场景 重点关注
Web / API 服务 文件描述符、监听队列、连接复用、TIME_WAIT、端口范围。
网关 / 反向代理 somaxconn、tcp_max_syn_backlog、ip_local_port_range、连接跟踪。
数据库 文件描述符、IO、swappiness、THP、内存、连接数。
Elasticsearch / OpenSearch vm.max_map_count、文件描述符、内存锁定。
多网卡 / LVS / keepalived ARP 行为、rp_filter、路由策略。
容器节点 文件描述符、进程数、网络队列、conntrack。

建议先回答三个问题:

  1. 当前瓶颈是 CPU、内存、磁盘、网络还是连接数?
  2. 是单机瓶颈,还是上游 / 下游 / 数据库瓶颈?
  3. 修改参数后,用什么指标证明变好了?

sysctl 配置和生效方式

临时修改

临时修改适合验证,重启后失效:

sysctl -w net.core.somaxconn=4096

也可以直接写 /proc:

echo 4096 > /proc/sys/net/core/somaxconn

持久化修改

建议把自定义配置放到 /etc/sysctl.d/:

sudo vi /etc/sysctl.d/99-custom.conf

示例:

net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.ip_local_port_range = 1024 65000
fs.file-max = 2097152
vm.max_map_count = 262144

让所有 sysctl 配置生效:

sudo sysctl --system

只加载某个文件:

sudo sysctl -p /etc/sysctl.d/99-custom.conf

查看当前值:

sysctl net.core.somaxconn
cat /proc/sys/net/core/somaxconn

文件描述符:fs.file-max 与 ulimit

fs.file-max 是系统级文件句柄上限,但应用能打开多少文件,还受进程级限制影响。

查看系统级限制:

sysctl fs.file-max
cat /proc/sys/fs/file-nr

查看当前 shell 限制:

ulimit -n

查看某个进程限制:

cat /proc/<pid>/limits

常见配置:

fs.file-max = 2097152

进程级限制通常通过 /etc/security/limits.conf 或 systemd service 配置:

[Service]
LimitNOFILE=1048576

注意:只改 fs.file-max 不一定解决 Too many open files。如果应用由 systemd 管理,还要检查 service 的 LimitNOFILE。

进程 ID 上限:kernel.pid_max

kernel.pid_max 控制 PID 最大值。高并发短进程或容器节点可能需要适当调大。

kernel.pid_max = 4194303

但大多数服务瓶颈不是 PID 上限,而是线程数、文件描述符、内存或调度开销。不要把它当成通用性能开关。

vm.max_map_count

vm.max_map_count 控制单个进程可拥有的虚拟内存映射区域数量。Elasticsearch、OpenSearch、Logstash 等服务经常要求设置为:

vm.max_map_count = 262144

验证:

sysctl vm.max_map_count

这类参数应该按应用官方要求配置,不建议无理由设置得过高。

swappiness

vm.swappiness 控制内核使用 swap 的倾向,范围通常是 0~100。

常见配置:

vm.swappiness = 1

不建议无脑设置为 0。对于数据库服务器,较低的 swappiness 可以减少活跃数据被换出;但如果完全禁止 swap 或内存规划不足,可能导致 OOM 风险增加。

建议:

  • 数据库:低 swappiness,并合理规划内存;
  • 普通应用服务器:结合内存容量和 OOM 风险决定;
  • Kubernetes / 容器节点:遵循发行版和集群策略。

Magic SysRq:kernel.sysrq

kernel.sysrq 控制 Magic SysRq 功能。需要注意:它不是简单的 0 / 1 / 2 三档。

常见值:

值 含义
0 禁用 SysRq。
1 启用所有 SysRq 功能。
大于 1 按 bitmask 启用部分功能。

例如生产环境可以按需启用部分安全功能,而不是直接打开全部能力。配置前建议阅读内核官方 SysRq 文档。

kernel.sysrq = 1

如果安全要求较高,应谨慎开启全部 SysRq。

TCP 监听队列:somaxconn 与 tcp_max_syn_backlog

net.core.somaxconn

net.core.somaxconn 限制 TCP listen backlog 的上限。

net.core.somaxconn = 4096

如果 Nginx、网关、Java 服务或数据库在高并发连接下出现连接排队,可以检查:

sysctl net.core.somaxconn
ss -lnt

注意应用本身也有 backlog 配置,例如 Nginx、Redis、Java 容器等。内核调大但应用 backlog 很小,效果也有限。

net.ipv4.tcp_max_syn_backlog

tcp_max_syn_backlog 控制半连接队列大小。

net.ipv4.tcp_max_syn_backlog = 8192

适用于突发连接多、SYN 队列溢出的场景。需要结合 SYN cookies 和应用连接队列一起看。

SYN Flood 防护:tcp_syncookies

net.ipv4.tcp_syncookies 用于在 SYN 队列溢出时启用 SYN cookies 机制,帮助缓解 SYN Flood。

net.ipv4.tcp_syncookies = 1

一般建议保持开启。它不是提升正常业务性能的参数,而是异常流量下的保护机制。

TIME_WAIT 相关参数

net.ipv4.tcp_max_tw_buckets

tcp_max_tw_buckets 限制系统允许的 TIME_WAIT socket 数量。

net.ipv4.tcp_max_tw_buckets = 200000

如果 TIME_WAIT 很多,先判断原因:

ss -ant state time-wait | wc -l
ss -s

TIME_WAIT 多不一定是问题。它是 TCP 正常关闭连接的一部分。真正需要关注的是:

  • 是否导致本地端口耗尽;
  • 是否导致内存消耗过大;
  • 是否是短连接过多;
  • 是否应该在应用层开启连接池或 HTTP keep-alive。

net.ipv4.tcp_tw_reuse

tcp_tw_reuse 允许在特定条件下复用 TIME_WAIT 连接。现代内核中它的行为和旧文章里的描述不完全一样,不建议把它当成通用优化项。

net.ipv4.tcp_tw_reuse = 0

除非明确理解内核版本和业务连接模式,否则建议保持默认或谨慎测试。

tcp_tw_recycle 不应继续使用

旧资料中常见:

net.ipv4.tcp_tw_recycle = 0

这个参数属于旧内核历史参数,后续 Linux 内核已经移除,不应作为现代 Linux 调优项继续推荐。尤其在 NAT 场景下,它曾经容易造成连接异常。

TCP 连接关闭和 KeepAlive

tcp_fin_timeout

tcp_fin_timeout 控制孤儿连接处于 FIN-WAIT-2 的时间。

net.ipv4.tcp_fin_timeout = 15

不要为了“减少连接数”盲目设置过低,可能影响慢连接或复杂网络环境中的正常关闭流程。

tcp_keepalive_time

tcp_keepalive_time 控制 TCP keepalive 探测前的空闲时间。

net.ipv4.tcp_keepalive_time = 600

KeepAlive 是否生效,还取决于应用是否启用 socket keepalive。数据库连接池、RPC 客户端、网关通常还需要应用层心跳和超时配置配合。

本地端口范围:ip_local_port_range

当机器作为大量出站连接客户端时,可能遇到本地临时端口耗尽。

查看端口范围:

sysctl net.ipv4.ip_local_port_range

常见配置:

net.ipv4.ip_local_port_range = 1024 65000

如果仍然耗尽,应优先检查:

  • 是否短连接过多;
  • 是否连接池没有复用;
  • TIME_WAIT 是否异常增长;
  • 上游服务是否慢导致连接占用过久。

ARP 与多网卡参数

rp_filter

rp_filter 是反向路径过滤,用于防止源地址欺骗。常见取值:

值 含义
0 关闭。
1 严格模式。
2 松散模式。

示例:

net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

但这不应作为通用推荐。只有在多网卡、策略路由、LVS、非对称路由等场景下,才需要考虑关闭或改为 loose mode。普通单网卡服务器可以保留发行版默认值。

arp_announce

arp_announce 常用于多网卡、多 IP、VIP、LVS 场景,减少 ARP flux 问题。

net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2

如果服务器只有普通单网卡,不一定需要修改。

neigh.default.gc_stale_time

net.ipv4.neigh.default.gc_stale_time 影响邻居缓存项的过期时间。

net.ipv4.neigh.default.gc_stale_time = 120

除非遇到 ARP 缓存、网关漂移、多网卡等问题,否则不建议盲目调整。

IPv6 是否禁用

旧配置里常见:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

现在不建议把禁用 IPv6 当成默认优化。是否禁用应取决于:

  • 业务是否使用 IPv6;
  • 云厂商 VPC 是否支持 IPv6;
  • 安全组、防火墙是否覆盖 IPv6;
  • 应用监听是否包含 IPv6 地址。

如果只是为了避免误监听,可以优先从应用监听地址、防火墙、安全组层面控制。

消息队列参数:kernel.msgmnb / kernel.msgmax

kernel.msgmnb = 65536
kernel.msgmax = 65536

这类 System V IPC 消息队列参数只有在应用确实使用对应机制时才有意义。大多数 Java Web、Nginx、MySQL 场景不需要专门调整。

网络缓冲区参数

常见参数:

net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

这些参数影响 socket 接收 / 发送缓冲区上限。适用于高吞吐、长肥网络、网关、代理、流媒体等场景。普通内网业务不一定需要调大。

推荐配置模板

下面模板只能作为起点,不能直接替代压测和监控。

Web / API 服务

fs.file-max = 2097152
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 600

还需要配合:

  • systemd LimitNOFILE;
  • Nginx / Java / Tomcat / Netty backlog;
  • 应用连接池;
  • 负载均衡和限流策略。

Elasticsearch / OpenSearch 节点

vm.max_map_count = 262144
fs.file-max = 2097152
vm.swappiness = 1

还要配合应用官方要求,例如 JVM heap、memlock、文件描述符、磁盘水位线等。

网关 / 代理节点

fs.file-max = 2097152
net.core.somaxconn = 8192
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_syncookies = 1

如果连接数非常高,还要关注 conntrack、NAT、端口耗尽、上游连接池和 keep-alive。

不建议盲目套用的参数

参数 建议
net.ipv4.tcp_tw_recycle 已是历史参数,不应继续推荐。
vm.swappiness = 0 不建议无脑设置,可能增加 OOM 风险。
net.ipv6.conf.*.disable_ipv6 = 1 不应作为默认优化,按业务和安全策略决定。
rp_filter = 0 只在多网卡 / 非对称路由等场景谨慎使用。
过大的 fs.file-max 系统级调大不代表进程限制已调大,还会掩盖应用泄漏问题。
过低的 tcp_fin_timeout 可能影响正常连接关闭。

调优验证清单

调优前后建议记录:

# 内核参数
sysctl -a > sysctl-before.txt
sysctl -a > sysctl-after.txt

# 连接状态
ss -s
ss -ant | awk '{print $1}' | sort | uniq -c

# 监听端口
ss -lntp

# 文件描述符
ulimit -n
cat /proc/sys/fs/file-nr
cat /proc/<pid>/limits

# 系统负载
uptime
vmstat 1
top

# 磁盘 IO
iostat -x 1

# 网络
sar -n TCP,ETCP 1
ip -s link

再配合 SysBench、业务压测或线上监控,对比:

  • TPS / QPS 是否变化;
  • P95 / P99 延迟是否变化;
  • CPU、IO、网络是否成为新瓶颈;
  • 错误率是否下降;
  • 连接队列溢出、端口耗尽、文件句柄耗尽是否消失。

小结

Linux 参数调优的核心原则是:

  1. 先定位瓶颈;
  2. 再按场景修改参数;
  3. 修改前后保留配置快照;
  4. 用压测和监控验证;
  5. 不盲目复制历史配置,尤其是已废弃或有副作用的网络参数。

调优不是一次性操作,而是容量规划、监控告警、压测验证和应用架构一起配合的过程。

参考资料

  • Linux kernel 官方文档:sysctl
  • Linux kernel 官方文档:IP sysctl
  • Linux kernel 官方文档:Magic SysRq
  • man7:sysctl(8)
  • man7:proc_sys_net(5)
  • SysBench 压测实践:CPU、内存、FileIO 与 MySQL OLTP 基准测试指南
  • Linux 常用命令速查:磁盘、日志、进程、网络、Docker 与文件排查实践
Linux, 指南
Linux 性能调优 内核参数 网络参数 sysctl TCP 高并发 系统优化
License:  CC BY 4.0
Share

Further Reading

Oct 17, 2022

Linux 内核与网络参数调优:sysctl、文件描述符、TCP 队列与高并发配置

系统整理 Linux sysctl 调优方法,覆盖文件描述符、进程数、TCP 连接队列、TIME_WAIT、SYN Flood、端口范围、rp_filter、ARP、swappiness 与 vm.max_map_count,并强调参数适用场景、风险和压测验证。

Nov 25, 2021

Linux 常用命令速查:磁盘、日志、进程、网络、Docker 与文件排查实践

按运维排查场景整理 Linux 常用命令,覆盖磁盘空间、日志检索、进程资源、网络端口、防火墙、文件查找、文本处理、压缩解压、权限用户和 Docker 容器排查。

OLDER

SysBench 压测实践:CPU、内存、FileIO 与 MySQL OLTP 基准测试指南

NEWER

APISIX kafka-logger 日志采集实践:写入 Kafka 并接入 Elasticsearch / Kibana

Recently Updated

  • Agent 架构设计原则:Router、Runtime 与 Business Script 的职责划分
  • RocketMQ 架构设计与应用最佳实践:高可用消息队列核心解析
  • Redis 核心概念、数据结构与高可用架构详解
  • B+树原理与 MySQL InnoDB 索引机制解析
  • MySQL AUTO_INCREMENT 插入 0 变成自增值的原因与解决方案

Trending Tags

RocketMQ Windows Feign Docker Zipkin SonarQube OkHttp HttpClient API 性能优化

Contents

©2026 Ryan's Blog. Some rights reserved. · 粤ICP备2022031588号