Linux 内核的网络栈有数百个可调参数,分散在
/proc/sys/net/
的各个子目录下。很多工程师要么不敢动、要么乱调一通——要么保守到错失性能,要么激进到引发故障。本文的目标不是列出所有参数,而是讲清楚哪些参数值得调、为什么要调、调多少、怎么验证效果。
一、参数体系总览
1.1 /proc/sys/net/ 目录结构
/proc/sys/net/
├── core/ # 通用网络核心参数
│ ├── somaxconn # listen() backlog 上限
│ ├── netdev_max_backlog # 网卡收包队列长度
│ ├── rmem_default # 默认接收缓冲区
│ ├── rmem_max # 最大接收缓冲区
│ ├── wmem_default # 默认发送缓冲区
│ ├── wmem_max # 最大发送缓冲区
│ ├── optmem_max # 辅助数据缓冲区
│ └── busy_poll # 忙轮询超时
├── ipv4/ # IPv4/TCP/UDP 参数
│ ├── tcp_* # TCP 相关(最多)
│ ├── ip_* # IP 层参数
│ ├── conf/ # 接口级 IP 配置
│ └── neigh/ # ARP 邻居表
├── ipv6/ # IPv6 参数
├── netfilter/ # conntrack 相关
│ ├── nf_conntrack_max # 连接追踪表大小
│ └── nf_conntrack_* # 各协议超时
└── unix/ # Unix domain socket
1.2 查看和修改参数
# 查看单个参数
sysctl net.core.somaxconn
cat /proc/sys/net/core/somaxconn
# 临时修改(重启后失效)
sysctl -w net.core.somaxconn=65535
# 永久修改
echo "net.core.somaxconn = 65535" >> /etc/sysctl.d/99-network.conf
sysctl -p /etc/sysctl.d/99-network.conf
# 查看所有网络参数
sysctl -a 2>/dev/null | grep "^net\." | wc -l # 通常 500+
# 查看当前值与默认值的差异
# 没有直接命令,需要对比新装系统二、收发缓冲区调优
2.1 TCP 缓冲区参数
TCP 缓冲区大小直接影响吞吐量——缓冲区太小,窗口满了就得等 ACK;缓冲区太大,浪费内存。
# TCP 内存管理三元组:[min, pressure, max](单位:page,通常 4KB)
sysctl net.ipv4.tcp_mem
# 示例输出:87381 116508 174762
# min = 87381 pages ≈ 341 MB — TCP 总内存低于此值时不受限
# pressure = 116508 pages ≈ 455 MB — 进入压力模式,开始回收
# max = 174762 pages ≈ 682 MB — TCP 总内存上限
# TCP 接收缓冲区三元组:[min, default, max](单位:字节)
sysctl net.ipv4.tcp_rmem
# 示例输出:4096 131072 6291456
# min = 4096 — 每个 socket 最少 4KB
# default = 131072 — 默认 128KB
# max = 6291456 — 最大 6MB(自动调优的上限)
# TCP 发送缓冲区三元组
sysctl net.ipv4.tcp_wmem
# 示例输出:4096 16384 41943042.2 自动调优机制
Linux 内核有 TCP 缓冲区自动调优(autotuning),会根据网络条件动态调整缓冲区大小:
# 启用/禁用自动调优
sysctl net.ipv4.tcp_moderate_rcvbuf
# 1 = 启用(默认),0 = 禁用
# 自动调优的工作原理:
# 1. 新连接从 tcp_rmem[1](default)开始
# 2. 内核根据 RTT 和带宽动态增大缓冲区
# 3. 不超过 tcp_rmem[2](max)
# 4. 如果 TCP 总内存超过 tcp_mem[1],进入压力模式,缩小缓冲区
# 带宽-延迟积(BDP)计算
# BDP = Bandwidth × RTT
# 示例:1 Gbps, 10ms RTT
# BDP = 1,000,000,000 / 8 × 0.010 = 1,250,000 bytes ≈ 1.2 MB
# 缓冲区至少要 >= BDP 才能跑满带宽2.3 高带宽长延迟场景调优
# 场景:跨大洲数据传输
# 带宽 10 Gbps,RTT 100ms
# BDP = 10,000,000,000 / 8 × 0.100 = 125,000,000 bytes ≈ 125 MB
# 调优配置
cat > /etc/sysctl.d/99-high-bandwidth.conf << 'EOF'
# TCP 缓冲区——适配 10Gbps × 100ms
net.ipv4.tcp_rmem = 4096 1048576 134217728
net.ipv4.tcp_wmem = 4096 1048576 134217728
# Socket 层面的全局上限
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
# TCP 总内存上限(需要足够大以支持多连接)
# 单位:page(4KB)
# 134217728 * 100 connections / 4096 ≈ 3276800 pages
net.ipv4.tcp_mem = 1638400 2457600 3276800
# 保持自动调优开启
net.ipv4.tcp_moderate_rcvbuf = 1
# 窗口缩放(默认开启,确认一下)
net.ipv4.tcp_window_scaling = 1
EOF
sysctl -p /etc/sysctl.d/99-high-bandwidth.conf2.4 缓冲区调优验证
# 1. 用 ss 查看 socket 实际缓冲区大小
ss -tim | head -20
# 输出中的关键字段:
# rcv_space: 接收窗口自动调优的目标值
# rcv_ssthresh: 接收慢启动阈值
# snd_wnd: 发送窗口大小
# 2. 用 iperf3 验证吞吐量
# 服务端
iperf3 -s
# 客户端——设置窗口大小
iperf3 -c server_ip -w 128M -t 30
# 3. 对比调优前后
# 调优前
iperf3 -c server_ip -t 10 -J | jq '.end.sum_sent.bits_per_second'
# 调优后
sysctl -p /etc/sysctl.d/99-high-bandwidth.conf
iperf3 -c server_ip -t 10 -J | jq '.end.sum_sent.bits_per_second'三、连接队列与 Backlog
3.1 两级队列模型
TCP 服务器接收连接经过两个队列:SYN 队列(半连接)和 Accept 队列(全连接):
客户端 服务器
│ │
│─── SYN ──────────────→│
│ ┌────┴────┐
│ │ SYN 队列 │ ← tcp_max_syn_backlog
│ │(半连接) │
│←── SYN+ACK ──────┤ │
│ └────┬────┘
│─── ACK ──────────────→│
│ ┌────┴────┐
│ │Accept队列│ ← min(somaxconn, backlog)
│ │(全连接) │
│ └────┬────┘
│ │
│ accept()
3.2 队列参数调优
# Accept 队列上限
# 实际大小 = min(net.core.somaxconn, listen(fd, backlog) 的 backlog 参数)
sysctl net.core.somaxconn
# 默认值:4096(旧内核为 128)
# 高并发场景建议:65535
# SYN 队列上限(半连接队列)
sysctl net.ipv4.tcp_max_syn_backlog
# 默认值:1024 或 2048
# 高并发场景建议:65535
# 查看队列溢出
# Accept 队列溢出
netstat -s | grep "overflowed"
# SYN 队列溢出
netstat -s | grep "dropped"
# 或者用 nstat 查看增量
nstat -az TcpExtListenOverflows TcpExtListenDrops
# Accept 队列满时的行为
sysctl net.ipv4.tcp_abort_on_overflow
# 0(默认):丢弃 ACK,客户端会重传(静默丢弃)
# 1:发送 RST,客户端立即收到 "Connection reset"
# 建议保持 0,除非需要快速失败3.3 网卡收包队列
# 网卡驱动到协议栈之间的队列
sysctl net.core.netdev_max_backlog
# 默认值:1000
# 高吞吐场景建议:10000-50000
# 网卡中断合并(减少 CPU 中断)
# 查看当前设置
ethtool -c eth0
# 设置中断合并参数
ethtool -C eth0 rx-usecs 50 rx-frames 64
# 多队列网卡的 RSS(Receive Side Scaling)
ethtool -l eth0 # 查看队列数
ethtool -L eth0 combined 8 # 设置 8 个收发队列四、TIME_WAIT 管理
4.1 TIME_WAIT 的工程影响
# 查看 TIME_WAIT 连接数
ss -s | grep TIME-WAIT
# 或者
ss -tan state time-wait | wc -l
# TIME_WAIT 的作用:
# 1. 确保最后一个 ACK 被对端收到
# 2. 等待旧连接的迟到包过期
# TIME_WAIT 持续时间 = 2 × MSL(通常 60s)4.2 TIME_WAIT 调优参数
# 允许 TIME_WAIT socket 被新连接复用
sysctl net.ipv4.tcp_tw_reuse
# 0(默认):禁用
# 1:启用——仅对客户端有效(connect 调用)
# 2:对 loopback 地址也启用
# 建议:客户端设为 1
# 最大 TIME_WAIT 数量
sysctl net.ipv4.tcp_max_tw_buckets
# 默认值:65536 或更高
# 超过时内核会销毁 TIME_WAIT socket 并打印警告
# TCP 时间戳(tcp_tw_reuse 的前提)
sysctl net.ipv4.tcp_timestamps
# 必须开启(默认 1)才能安全使用 tcp_tw_reuse
# !!!! 注意 !!!!
# net.ipv4.tcp_tw_recycle 在 Linux 4.12 后已移除
# 它在 NAT 环境下会导致大量连接失败
# 绝对不要使用4.3 高并发短连接场景
# 场景:反向代理(大量到后端的短连接)
# 症状:大量 TIME_WAIT 占用端口
cat > /etc/sysctl.d/99-high-concurrency.conf << 'EOF'
# 允许 TIME_WAIT 复用
net.ipv4.tcp_tw_reuse = 1
# 可用端口范围(默认 32768-60999)
net.ipv4.ip_local_port_range = 1024 65535
# TIME_WAIT 桶上限
net.ipv4.tcp_max_tw_buckets = 200000
# 开启时间戳
net.ipv4.tcp_timestamps = 1
# FIN_WAIT2 超时(默认 60s)
net.ipv4.tcp_fin_timeout = 15
EOF
sysctl -p /etc/sysctl.d/99-high-concurrency.conf五、conntrack 连接追踪
5.1 conntrack 概述
conntrack 是 Netfilter 框架的连接追踪模块。使用 iptables/nftables 做 NAT 或状态防火墙时会自动加载。
# 查看 conntrack 表当前状态
conntrack -C # 当前连接数
conntrack -L 2>/dev/null | wc -l # 列出所有连接
# conntrack 表大小
sysctl net.netfilter.nf_conntrack_max
# 默认值:65536 或根据内存自动计算
# 每条记录约占 320 字节
# conntrack 表满时的症状
# dmesg 中出现:nf_conntrack: table full, dropping packet
# 新连接无法建立,表现为随机丢包
# 查看是否有 conntrack 丢包
dmesg | grep "nf_conntrack: table full"
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max5.2 conntrack 调优
# 增大 conntrack 表
sysctl -w net.netfilter.nf_conntrack_max=1048576
# Hash 表大小(只能在加载模块时设置)
echo "options nf_conntrack hashsize=262144" > /etc/modprobe.d/nf_conntrack.conf
# 缩短超时时间以加速条目回收
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_close_wait=30
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_fin_wait=30
sysctl -w net.netfilter.nf_conntrack_udp_timeout=30
sysctl -w net.netfilter.nf_conntrack_udp_timeout_stream=120
# 对不需要 NAT/状态跟踪的流量禁用 conntrack
# 使用 raw 表的 NOTRACK
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport 80 -j NOTRACK5.3 conntrack 容量规划
| 并发连接数 | conntrack_max | Hash 表大小 | 内存占用 |
|---|---|---|---|
| 10 万 | 131072 | 32768 | ~40 MB |
| 50 万 | 524288 | 131072 | ~160 MB |
| 100 万 | 1048576 | 262144 | ~320 MB |
| 500 万 | 5242880 | 1310720 | ~1.6 GB |
六、SYN Flood 防护参数
# SYN Cookie——当 SYN 队列满时启用
sysctl net.ipv4.tcp_syncookies
# 1(默认):启用
# SYN Cookie 不占队列空间,但会丢失 TCP 选项(窗口缩放、SACK)
# SYN 重试次数
sysctl net.ipv4.tcp_syn_retries
# 默认 6(约 127 秒),建议 2-3
# SYN+ACK 重试次数
sysctl net.ipv4.tcp_synack_retries
# 默认 5(约 63 秒),建议 2-3
# 综合防护配置
cat > /etc/sysctl.d/99-syn-flood.conf << 'EOF'
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_max_syn_backlog = 65535
net.core.somaxconn = 65535
EOF七、Keepalive 参数
# TCP Keepalive 参数
sysctl net.ipv4.tcp_keepalive_time
# 默认 7200(2小时)——多久没数据后开始探测
# 高可用场景建议:600(10分钟)
sysctl net.ipv4.tcp_keepalive_intvl
# 默认 75(秒)——探测间隔
# 建议:15-30
sysctl net.ipv4.tcp_keepalive_probes
# 默认 9——探测次数
# 建议:5
# 完整配置
# 600 + 15 × 5 = 675 秒后发现死连接
cat > /etc/sysctl.d/99-keepalive.conf << 'EOF'
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
EOF7.2 TCP 内存压力诊断
# 查看 TCP 内存使用
cat /proc/net/sockstat
# sockets: used 1500
# TCP: inuse 800 orphan 10 tw 200 alloc 900 mem 15000
# "mem" 字段单位是 page(4KB),15000 pages ≈ 58 MB
# 查看 TCP 内存限制
sysctl net.ipv4.tcp_mem
# 87381 116508 174762(页)
# 当 mem 接近 tcp_mem[1] 时,内核进入"内存压力"模式
# 表现:新连接的缓冲区被限制在 tcp_rmem[0],吞吐量骤降
# 查看是否进入了内存压力
cat /proc/net/sockstat | awk '/TCP:/{print "TCP mem:", $NF, "pages"}'
sysctl net.ipv4.tcp_mem | awk '{print "pressure threshold:", $2, "pages"}'
# 如果 mem > pressure,增大 tcp_mem
# 注意:tcp_mem 的单位是 page,不是字节八、参数调优方法论
8.1 系统化流程
┌────────────┐
│ 1. 确定目标 │ 吞吐量?延迟?并发数?
└─────┬──────┘
↓
┌────────────┐
│ 2. 基准测试 │ 用 iperf3/wrk/ab 测量当前性能
└─────┬──────┘
↓
┌────────────┐
│ 3. 瓶颈分析 │ 查看 netstat -s、ss -ti、dmesg
└─────┬──────┘
↓
┌────────────┐
│ 4. 调整参数 │ 每次只改一个参数或一组相关参数
└─────┬──────┘
↓
┌────────────┐
│ 5. 验证效果 │ 重跑基准测试,对比前后
└─────┬──────┘
↓
┌────────────┐
│ 6. 持久化 │ 写入 /etc/sysctl.d/
└────────────┘
8.2 常见问题诊断
| 症状 | 可能原因 | 诊断命令 | 调优方向 |
|---|---|---|---|
| 新连接被拒 | Accept 队列满 | nstat TcpExtListenOverflows |
somaxconn |
| 连接超时多 | SYN 队列满 | nstat TcpExtTCPReqQFullDrop |
tcp_max_syn_backlog |
| 吞吐量低 | 缓冲区太小 | ss -tim 看 rcv_space |
tcp_rmem/tcp_wmem |
| 随机丢包 | conntrack 表满 | dmesg \| grep conntrack |
nf_conntrack_max |
| TIME_WAIT 多 | 短连接频繁 | ss -s |
tcp_tw_reuse |
| 延迟高 | Nagle + Delayed ACK | 应用层设置 TCP_NODELAY | 应用层 |
8.3 完整调优配置模板
cat > /etc/sysctl.d/99-network-tuning.conf << 'EOF'
### 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 10000
### TCP 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216
net.ipv4.tcp_moderate_rcvbuf = 1
### TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_fin_timeout = 15
### Keepalive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
### SYN Flood 防护
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
### conntrack(如果使用 iptables/NAT)
# net.netfilter.nf_conntrack_max = 1048576
# net.netfilter.nf_conntrack_tcp_timeout_established = 3600
### 其他
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_no_metrics_save = 1
EOF
sysctl -p /etc/sysctl.d/99-network-tuning.conf九、中断亲和与软中断
9.1 中断亲和(IRQ Affinity)
网卡中断默认可能集中在 CPU 0 上,导致单核瓶颈。合理分配中断到多个 CPU 可以显著提升吞吐量。
# 查看网卡中断分布
cat /proc/interrupts | grep eth0
# 或者查看多队列网卡
cat /proc/interrupts | grep -E "eth0-TxRx|ens"
# 查看某个中断的 CPU 亲和性
cat /proc/irq/48/smp_affinity_list
# 输出 "0" 表示绑定到 CPU 0
# 手动设置中断亲和——将不同队列绑定到不同 CPU
# 队列 0 → CPU 0, 队列 1 → CPU 1, ...
for i in $(seq 0 7); do
irq=$(grep "eth0-TxRx-$i" /proc/interrupts | awk '{print $1}' | tr -d ':')
[ -n "$irq" ] && echo $i > /proc/irq/$irq/smp_affinity_list
done
# 使用 irqbalance 服务自动分配(大多数场景推荐)
systemctl status irqbalance
# irqbalance 会自动将中断分散到各 CPU
# 但在高性能场景下手动绑定可能更好9.2 RPS/RFS/XPS
当网卡不支持多队列 RSS 时,可以用软件方式将包处理分散到多个 CPU:
# RPS(Receive Packet Steering)——软件层面的收包分发
# 将某个队列的包分发到多个 CPU 处理
# 掩码 ff 表示使用 CPU 0-7
echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus
# RFS(Receive Flow Steering)——将包导向处理该连接的 CPU
# 减少 CPU 缓存未命中
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
# XPS(Transmit Packet Steering)——发送方向的 CPU 亲和
# 将发送队列绑定到特定 CPU
echo 1 > /sys/class/net/eth0/queues/tx-0/xps_cpus # CPU 0
echo 2 > /sys/class/net/eth0/queues/tx-1/xps_cpus # CPU 1
echo 4 > /sys/class/net/eth0/queues/tx-2/xps_cpus # CPU 2| 技术 | 方向 | 硬件要求 | 效果 |
|---|---|---|---|
| RSS | 接收 | 多队列网卡 | 硬件分发到多 CPU |
| RPS | 接收 | 无 | 软件模拟 RSS |
| RFS | 接收 | 无 | 包导向处理线程所在 CPU |
| XPS | 发送 | 无 | 减少发送锁竞争 |
9.3 Busy Polling
对于延迟极敏感的场景,可以让 CPU 主动轮询网卡而不是等待中断:
# 全局启用 busy polling
sysctl -w net.core.busy_poll=50 # 轮询 50 微秒
sysctl -w net.core.busy_read=50 # 阻塞读时轮询 50 微秒
# 或者在 socket 级别启用
# setsockopt(fd, SOL_SOCKET, SO_BUSY_POLL, &poll_usecs, sizeof(poll_usecs));
# 代价:CPU 使用率增加,换取延迟降低
# 适用场景:金融交易、实时通信
# 不适用场景:CPU 资源紧张的通用服务器十、拥塞控制算法选择
# 查看可用的拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control
# 输出:reno cubic bbr
# 查看当前使用的算法
sysctl net.ipv4.tcp_congestion_control
# 默认:cubic
# 切换到 BBR
modprobe tcp_bbr
sysctl -w net.ipv4.tcp_congestion_control=bbr
# 验证
sysctl net.ipv4.tcp_congestion_control
ss -tin | grep -o "bbr" | head -5| 算法 | 适用场景 | 特点 |
|---|---|---|
| cubic | 通用默认 | 基于丢包的拥塞控制,公平性好 |
| bbr | 高带宽高延迟 | 基于带宽估计,不惧轻微丢包 |
| reno | 兼容性 | 最基础的 AIMD,现在很少使用 |
# BBR + fq 队列规则的组合
# BBR 配合 fq(Fair Queue)效果最佳
tc qdisc replace dev eth0 root fq pacing
# 持久化
cat >> /etc/sysctl.d/99-network-tuning.conf << 'EOF'
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF十一、ARP/邻居表调优
在大型二层网络中(尤其是容器环境),ARP/邻居表可能溢出:
# ARP 表参数
sysctl net.ipv4.neigh.default.gc_thresh1
# 默认 128 — 开始垃圾回收的最低条目数
sysctl net.ipv4.neigh.default.gc_thresh2
# 默认 512 — 触发更积极 GC 的条目数
sysctl net.ipv4.neigh.default.gc_thresh3
# 默认 1024 — 硬上限,超过则无法创建新条目
# 大规模环境调优
cat >> /etc/sysctl.d/99-network-tuning.conf << 'TUNING_EOF'
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
net.ipv6.neigh.default.gc_thresh1 = 4096
net.ipv6.neigh.default.gc_thresh2 = 8192
net.ipv6.neigh.default.gc_thresh3 = 16384
TUNING_EOF
# 查看 ARP 表当前大小
ip neigh show | wc -l
# 查看 ARP 表溢出错误
dmesg | grep "neighbour table overflow"| 场景 | gc_thresh3 建议值 |
|---|---|
| 普通服务器 | 1024(默认) |
| 容器宿主机(100+ Pod) | 16384 |
| 大型二层网络(1000+ 主机) | 65536 |
十二、实战案例
12.1 案例:Nginx 反向代理 TIME_WAIT 堆积
现象:Nginx 反代后端服务,高峰期
ss -s 显示 6 万+ TIME_WAIT,偶发
cannot assign requested address 错误。
分析:
# 1. 确认 TIME_WAIT 数量
ss -s
# TCP: 85000 (estab 20000, closed 0, orphaned 0, timewait 65000)
# 2. 确认可用端口范围
sysctl net.ipv4.ip_local_port_range
# 32768 60999 → 只有 28231 个端口
# 3. 确认 tcp_tw_reuse 状态
sysctl net.ipv4.tcp_tw_reuse
# 0 → 未开启
# 4. TIME_WAIT 的四元组:src_ip:src_port → dst_ip:dst_port
# 到同一后端 IP:Port 的连接,最多 28231 个端口可用
# 减去 TIME_WAIT 中的端口,可用端口耗尽解决:
# 方案一:启用 tcp_tw_reuse + 扩大端口范围
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w net.ipv4.tcp_fin_timeout=15
# 方案二:Nginx 配置长连接到后端(根本解决)
# upstream backend {
# server 10.0.0.1:8080;
# keepalive 256; # 保持 256 个长连接
# keepalive_requests 10000; # 每个连接最多 10000 请求
# keepalive_timeout 60s; # 空闲超时
# }
#
# location / {
# proxy_http_version 1.1;
# proxy_set_header Connection ""; # 清除 "close"
# proxy_pass http://backend;
# }结果:方案二上线后 TIME_WAIT 从 6 万+ 降到 500 以内。
12.2 案例:conntrack 表满导致间歇丢包
现象:K8s 集群中某些 Pod
间歇性连接超时,kubectl exec 偶尔也超时。
分析:
# 1. 检查 dmesg
dmesg | tail -50
# [12345.678] nf_conntrack: table full, dropping packet
# 2. 查看 conntrack 使用率
cat /proc/sys/net/netfilter/nf_conntrack_count
# 131072
cat /proc/sys/net/netfilter/nf_conntrack_max
# 131072 → 已满!
# 3. 分析 conntrack 条目分布
conntrack -L 2>/dev/null | \
awk '{print $3}' | sort | uniq -c | sort -rn
# 120000 tcp
# 10000 udp
# 1072 icmp
# 4. 检查 ESTABLISHED 超时
sysctl net.netfilter.nf_conntrack_tcp_timeout_established
# 432000 (5天) → 太长!解决:
# 增大表 + 缩短超时
sysctl -w net.netfilter.nf_conntrack_max=524288
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
# 对高流量端口跳过 conntrack
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
iptables -t raw -A PREROUTING -p tcp --dport 443 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport 80 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport 443 -j NOTRACK8.4 调优注意事项
| 注意事项 | 说明 |
|---|---|
| 不要盲目抄配置 | 每个参数都要理解其含义和副作用 |
| 每次只改一组 | 否则无法判断哪个参数产生了效果 |
| 先测后改 | 没有基准数据的调优是盲目的 |
| 监控副作用 | 某些参数改大会增加内存消耗 |
| 内核版本差异 | 不同内核版本的默认值和行为可能不同 |
| NAT 环境谨慎 | tcp_tw_recycle 在 NAT 下会出问题(已移除) |
| 容器环境 | 容器内的 sysctl 可能受宿主机限制 |
参考文献
- Linux Kernel Documentation, “IP Sysctl,” kernel.org/doc/Documentation/networking/ip-sysctl.rst.
- Hemminger, S., “TCP Tuning Guide,” Linux Foundation.
- Corbet, J., “TCP small queues,” LWN.net, 2012.
- Benvenuti, C., “Understanding Linux Network Internals,” O’Reilly, 2005.
- Stewart, R., “TCP/IP Illustrated, Volume 1,” Addison-Wesley, 2011.
- Linux man pages, “tcp(7), socket(7), ip(7).”
- Gregg, B., “BPF Performance Tools,” Addison-Wesley, 2019.
- Red Hat, “Performance Tuning Guide,” access.redhat.com/documentation.
- Cloudflare Blog, “How to achieve low latency with 10Gbps Ethernet,” 2015.
上一篇: 网络取证:流量分析、异常检测与事件响应 下一篇: 网络性能基准测试:iperf3、netperf 与测试方法论
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【网络工程】TCP 调优实战:内核参数与 socket 选项完全指南
TCP 内核参数和 socket 选项是网络性能的最后一道关卡。本文系统梳理 Linux TCP 参数体系,从缓冲区、Backlog 队列、Keepalive、TIME_WAIT 到拥塞控制,给出不同场景的调优模板和基准测试方法论。
【网络工程】网络延迟优化:Nagle、TCP_NODELAY 与中断亲和
网络延迟优化是延迟敏感应用的核心关注点。本文从 Nagle 算法与 Delayed ACK 的经典交互问题出发,系统讲解 TCP_NODELAY 和 TCP_CORK 的正确用法、中断亲和与 RPS/RFS、Busy Polling、socket 调优、应用层延迟优化,以及延迟分解和定位方法论。
【网络工程】TCP 连接管理:三次握手、四次挥手与状态机
深入剖析 TCP 连接的完整生命周期——三次握手的每个细节、四次挥手的工程陷阱、11 个状态的实测观察,以及 TIME_WAIT 堆积、SYN Flood 防御、端口复用等生产环境高频问题的系统化解决方案。
【网络工程】TCP 可靠传输:序列号、确认与重传机制
从工程视角剖析 TCP 可靠传输的核心机制——序列号与确认的精确语义、RTO 计算的数学基础、快速重传与 SACK 的工程价值、DSACK 的重复检测,以及重传对延迟的放大效应与实际诊断方法。