HiHuo
首页
博客
手册
工具
首页
博客
手册
工具
  • 系统底层修炼

    • 操作系统核心知识学习指南
    • CPU调度与上下文切换
    • CFS调度器原理与源码
    • 内存管理与虚拟内存
    • PageCache与内存回收
    • 文件系统与IO优化
    • 零拷贝与Direct I/O
    • 网络子系统架构
    • TCP协议深度解析
    • TCP问题排查实战
    • 网络性能优化
    • epoll与IO多路复用
    • 进程与线程管理
    • Go Runtime调度器GMP模型
    • 系统性能分析方法论
    • DPDK与用户态网络栈
    • eBPF与内核可观测性
    • 综合实战案例

网络性能优化

章节概述

网络性能优化是高性能系统的关键环节。本章将系统性地讲解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)

复习题

选择题

  1. BBR算法的主要优势是?

    • A. CPU占用低
    • B. 高丢包场景性能好
    • C. 内存占用少
    • D. 延迟最低
  2. tcp_tw_reuse参数对什么有效?

    • A. 服务端
    • B. 客户端
    • C. 双向
    • D. 都无效
  3. 哪个参数控制SYN队列大小?

    • A. somaxconn
    • B. tcp_max_syn_backlog
    • C. netdev_max_backlog
    • D. tcp_fin_timeout

简答题

  1. 解释CUBIC和BBR的核心区别。
  2. 为什么需要tcp_tw_reuse?它解决了什么问题?
  3. 如何验证BBR是否生效?
  4. 缓冲区大小如何影响网络性能?

实战题

  1. 优化题: 给定一个跨国HTTP API服务,延迟200ms,丢包率2%,设计网络优化方案。

  2. 诊断题: 一个Web服务器QPS只有5000,但CPU和网卡都未饱和,如何排查和优化?

  3. 对比题: 使用iperf3对比CUBIC和BBR在高延迟网络下的性能差异。

扩展阅读

  • BBR论文
  • Linux网络调优指南
  • Cloudflare - BBR分析

下一章预告: epoll与IO多路复用,深入理解高并发网络编程的核心技术。

Prev
TCP问题排查实战
Next
epoll与IO多路复用