网络性能优化
章节概述
网络性能优化是高性能系统的关键环节。本章将系统性地讲解Linux网络性能优化技术,包括内核参数调优、拥塞控制算法选择、以及各种网络优化技术的对比和应用场景。
学习目标:
- 掌握关键网络内核参数的含义和调优方法
- 理解BBR、CUBIC等拥塞控制算法的差异
- 学会使用工具进行网络性能测试和分析
- 能够针对不同场景选择合适的优化策略
核心概念
1. 网络性能指标
关键指标:
带宽 (Bandwidth)
- 单位时间内传输的数据量
- 单位:Mbps, Gbps
- 受限于:网卡、交换机、带宽
延迟 (Latency)
- 数据传输所需时间
- 单位:ms, μs
- 受限于:物理距离、网络跳数、处理时间
吞吐量 (Throughput)
- 实际可用的数据传输速率
- 通常小于带宽
- 受限于:TCP参数、拥塞控制
PPS (Packets Per Second)
- 每秒处理的数据包数量
- 重要的性能指标
- 受限于:CPU、网卡、驱动
连接数
- 并发TCP连接数量
- 受限于:端口范围、文件描述符、内存
性能层次:
应用层性能
↓ 受限于
协议栈性能 (TCP/IP)
↓ 受限于
网卡性能 (驱动、DMA)
↓ 受限于
物理网络 (带宽、延迟)
2. TCP参数全景
连接建立相关:
net.ipv4.tcp_max_syn_backlog
- SYN队列最大长度
- 默认:128 → 建议:8192
- 影响:抗SYN Flood能力
net.core.somaxconn
- accept队列最大长度
- 默认:128 → 建议:1024+
- 影响:高并发连接能力
net.ipv4.tcp_syncookies
- SYN Cookie保护
- 默认:1 (启用)
- 作用:防SYN Flood攻击
缓冲区相关:
net.core.rmem_max / wmem_max
- Socket接收/发送缓冲区最大值
- 默认:212992 → 建议:16777216 (16MB)
net.core.rmem_default / wmem_default
- Socket接收/发送缓冲区默认值
- 默认:212992 → 建议:262144 (256KB)
net.ipv4.tcp_rmem / tcp_wmem
- TCP接收/发送缓冲区 (min, default, max)
- 默认:4096 87380 6291456
- 建议:4096 87380 16777216
连接复用相关:
net.ipv4.tcp_tw_reuse
- TIME_WAIT状态端口重用
- 默认:0 → 建议:1
- 注意:仅对客户端有效
net.ipv4.tcp_fin_timeout
- FIN_WAIT_2超时时间
- 默认:60秒 → 建议:30秒
- 影响:连接回收速度
net.ipv4.ip_local_port_range
- 本地端口范围
- 默认:32768 60999
- 建议:1024 65535
拥塞控制相关:
net.ipv4.tcp_congestion_control
- 拥塞控制算法
- 默认:cubic
- 可选:cubic, bbr, reno, htcp
net.ipv4.tcp_slow_start_after_idle
- 空闲后慢启动
- 默认:1 → 建议:0 (长连接场景)
3. 拥塞控制算法对比
CUBIC (默认算法):
特点:
- 基于丢包的拥塞控制
- 窗口增长函数是三次函数
- 适合高带宽、低延迟网络
优点:
- 稳定、成熟
- 带宽利用率高
- 公平性好
缺点:
- 丢包敏感
- 高延迟网络表现差
- Buffer Bloat问题
BBR (Bottleneck Bandwidth and RTT):
特点:
- 基于瓶颈带宽和RTT的拥塞控制
- 主动探测网络状况
- Google开发 (2016)
优点:
- 高丢包率下性能好
- 延迟低
- 吞吐量高
- 适合跨国、高延迟网络
缺点:
- 可能过于激进
- 与CUBIC共存时占用带宽多
- 需要Linux 4.9+
性能对比(1% 丢包率,100ms RTT):
算法 吞吐量 延迟
CUBIC 50Mbps 150ms
BBR 80Mbps 110ms
选择建议:
场景 建议算法
局域网/低延迟 CUBIC
跨国/高延迟/高丢包 BBR
移动网络 BBR
CDN/视频流 BBR
数据中心内部 CUBIC/DCTCP
内核参数详解
1. 接收端优化
# Socket接收缓冲区
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.rmem_default=262144
# TCP接收缓冲区自动调整
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
# 启用TCP窗口缩放
sysctl -w net.ipv4.tcp_window_scaling=1
# 接收队列长度
sysctl -w net.core.netdev_max_backlog=16384
# SYN队列
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
sysctl -w net.core.somaxconn=1024
2. 发送端优化
# Socket发送缓冲区
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.wmem_default=262144
# TCP发送缓冲区自动调整
sysctl -w net.ipv4.tcp_wmem="4096 16384 16777216"
# TCP Segmentation Offload
ethtool -K eth0 tso on
ethtool -K eth0 gso on
# 启用TCP Fast Open
sysctl -w net.ipv4.tcp_fastopen=3
3. 连接管理优化
# TIME_WAIT重用
sysctl -w net.ipv4.tcp_tw_reuse=1
# FIN超时
sysctl -w net.ipv4.tcp_fin_timeout=30
# 端口范围
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
# 连接追踪表大小
sysctl -w net.netfilter.nf_conntrack_max=1000000
# Keepalive
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=3
4. 拥塞控制优化
# 启用BBR
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr
# 或保持CUBIC
sysctl -w net.ipv4.tcp_congestion_control=cubic
# 禁用空闲后慢启动(长连接场景)
sysctl -w net.ipv4.tcp_slow_start_after_idle=0
# 启用TCP Forward Acknowledgment
sysctl -w net.ipv4.tcp_fack=1
# 启用SACK
sysctl -w net.ipv4.tcp_sack=1
️ 性能测试工具
1. iperf3 - 带宽测试
服务端:
# 启动服务器
iperf3 -s
# 指定端口
iperf3 -s -p 5201
客户端:
# TCP测试
iperf3 -c server_ip -t 30
# 输出示例:
# [ ID] Interval Transfer Bitrate
# [ 5] 0.00-30.00 sec 3.50 GBytes 1.00 Gbits/sec
# UDP测试
iperf3 -c server_ip -u -b 1G
# 并发连接测试
iperf3 -c server_ip -P 10
# 反向测试(服务端发送)
iperf3 -c server_ip -R
高级用法:
# JSON输出
iperf3 -c server_ip -J > result.json
# 设置TCP窗口大小
iperf3 -c server_ip -w 512K
# 设置MSS
iperf3 -c server_ip -M 1460
2. netperf - 综合网络测试
# 安装
sudo apt install netperf
# 服务端
netserver
# TCP_STREAM (吞吐量)
netperf -H server_ip -t TCP_STREAM
# TCP_RR (请求响应延迟)
netperf -H server_ip -t TCP_RR
# TCP_CRR (连接速率)
netperf -H server_ip -t TCP_CRR
# 自定义参数
netperf -H server_ip -t TCP_STREAM -- -m 1024 -M 1024
3. ss - 连接统计
# 查看连接统计
ss -s
# 输出:
# Total: 500 (kernel 800)
# TCP: 300 (estab 250, closed 20, orphaned 0, synrecv 0, timewait 15/0), ports 0
# 查看连接详情
ss -tanp | grep ESTAB
# 查看TCP信息
ss -ti
# 输出示例:
# cubic wscale:7,7 rto:204 rtt:3.5/2 ato:40 mss:1448
# pmtu:1500 rcvmss:1448 advmss:1448 cwnd:10
# bytes_acked:123456 segs_out:100 segs_in:80
ss输出详解:
cubic: 拥塞控制算法
wscale: 窗口缩放因子
rto: 重传超时
rtt: 往返时延 (平均/方差)
cwnd: 拥塞窗口
bytes_acked: 已确认字节数
segs_out/in: 发送/接收段数
retrans: 重传次数
4. tcpdump - 抓包分析
# 抓取指定主机的包
tcpdump -i eth0 host 192.168.1.100
# 抓取TCP SYN包
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
# 抓取大于1000字节的包
tcpdump -i eth0 'ip[2:2] > 1000'
# 保存到文件
tcpdump -i eth0 -w capture.pcap
# 分析延迟
tcpdump -i eth0 -ttt host server_ip
优化实践
1. Web服务器优化
Nginx配置:
# /etc/nginx/nginx.conf
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
# TCP优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Keepalive
keepalive_timeout 65;
keepalive_requests 1000;
# 上游连接池
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
}
}
系统参数:
# /etc/sysctl.conf
# 文件描述符
fs.file-max = 1000000
# 网络核心
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65536
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# TCP
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_slow_start_after_idle = 0
# BBR
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# 应用后生效
sysctl -p
2. 数据库服务器优化
# MySQL/PostgreSQL场景
# 连接数优化
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
# 缓冲区(数据库通常有自己的缓冲管理)
net.ipv4.tcp_rmem = "4096 87380 8388608"
net.ipv4.tcp_wmem = "4096 16384 8388608"
# Keepalive(检测死连接)
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
# 使用CUBIC(稳定性优先)
net.ipv4.tcp_congestion_control = cubic
3. CDN/视频流优化
# 大带宽、长距离传输
# 大缓冲区
net.core.rmem_max = 134217728 # 128MB
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = "4096 87380 67108864" # 64MB
net.ipv4.tcp_wmem = "4096 65536 67108864"
# BBR算法
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# TCP Fast Open
net.ipv4.tcp_fastopen = 3
# 禁用慢启动
net.ipv4.tcp_slow_start_after_idle = 0
常见问题
Q1: 什么时候应该使用BBR?
A: BBR适合:
- 跨国/长距离网络
- 高延迟网络 (>50ms)
- 丢包率较高的网络 (移动网络)
- 视频流/CDN服务
CUBIC适合:
- 局域网/数据中心
- 低延迟网络 (<10ms)
- 稳定性优先的场景
Q2: tcp_tw_reuse和tcp_tw_recycle的区别?
A:
tcp_tw_reuse
: 安全,推荐使用,仅客户端有效tcp_tw_recycle
: 危险,已在Linux 4.12移除,会导致NAT环境问题
只用tcp_tw_reuse!
Q3: 如何判断网络参数是否生效?
A: 验证方法:
# 查看当前参数
sysctl -a | grep tcp
# 使用ss查看实际连接
ss -ti
# iperf3测试对比
iperf3 -c server_ip -t 30
Q4: 缓冲区是越大越好吗?
A: 不是:
- 太大:增加延迟(Buffer Bloat)
- 太小:限制吞吐量
- 建议:让TCP自动调整(tcp_moderate_rcvbuf=1)
复习题
选择题
BBR算法的主要优势是?
- A. CPU占用低
- B. 高丢包场景性能好
- C. 内存占用少
- D. 延迟最低
tcp_tw_reuse参数对什么有效?
- A. 服务端
- B. 客户端
- C. 双向
- D. 都无效
哪个参数控制SYN队列大小?
- A. somaxconn
- B. tcp_max_syn_backlog
- C. netdev_max_backlog
- D. tcp_fin_timeout
简答题
- 解释CUBIC和BBR的核心区别。
- 为什么需要tcp_tw_reuse?它解决了什么问题?
- 如何验证BBR是否生效?
- 缓冲区大小如何影响网络性能?
实战题
优化题: 给定一个跨国HTTP API服务,延迟200ms,丢包率2%,设计网络优化方案。
诊断题: 一个Web服务器QPS只有5000,但CPU和网卡都未饱和,如何排查和优化?
对比题: 使用iperf3对比CUBIC和BBR在高延迟网络下的性能差异。
扩展阅读
下一章预告: epoll与IO多路复用,深入理解高并发网络编程的核心技术。