网络性能分析与优化

网络是分布式系统的关键组件,网络性能直接影响应用体验。

网络性能基础

OSI 模型与 TCP/IP

网络分层

应用层(HTTP/DNS)
  ↓
传输层(TCP/UDP)
  ↓
网络层(IP/ICMP)
  ↓
链路层(Ethernet)
  ↓
物理层(网卡/线缆)

网络性能指标

带宽(Bandwidth)

  • 网络链路的最大传输速率
  • 单位:Mbps、Gbps
  • 决定吞吐量上限

吞吐量(Throughput)

  • 实际传输速率
  • 受多种因素影响
  • 通常低于带宽

延迟(Latency)

组成:
  ├─ 传播延迟:信号传播时间(光速限制)
  ├─ 传输延迟:发送数据到链路的时间
  ├─ 处理延迟:交换机/路由器处理时间
  └─ 排队延迟:缓冲区等待时间

RTT(往返时间):
  └─ 数据包从发送到收到响应的时间

丢包率(Packet Loss)

  • 数据包丢失的比例
  • 影响 TCP 性能(重传)
  • 通常应 < 0.1%

抖动(Jitter)

  • 延迟的变化程度
  • 影响实时应用(VoIP、视频)
  • 抖动大导致体验差

TCP 性能原理

TCP 连接建立

三次握手

客户端                    服务器
  │                          │
  ├─── SYN ────────────────> │  1. 请求连接
  │                          │
  │ <──── SYN-ACK ─────────┤  2. 确认并请求
  │                          │
  ├─── ACK ────────────────> │  3. 确认
  │                          │
  └─ 连接建立,可传输数据
  
延迟影响:
  └─ 1.5 × RTT(三次握手 + 数据)

TCP Fast Open(TFO)

优化:
  ├─ 在 SYN 中携带数据
  ├─ 减少一个 RTT
  └─ 需要客户端和服务器都支持

拥塞控制

慢启动(Slow Start)

过程:
  1. 初始窗口小(IW = 10 segments)
  2. 每收到 ACK,窗口加倍
  3. 达到阈值后线性增长

影响:
  └─ 新连接吞吐量上升慢

拥塞避免

AIMD(加性增、乘性减):
  ├─ 无丢包:窗口 +1
  └─ 有丢包:窗口 ÷2

变种:
  ├─ Reno:快速重传、快速恢复
  ├─ Cubic:更激进的增长(Linux 默认)
  └─ BBR:基于带宽和延迟

流量控制

滑动窗口

发送窗口 = min(拥塞窗口, 接收窗口)

接收窗口:
  ├─ 接收方通告
  ├─ 防止接收缓冲区溢出
  └─ 动态调整

优化:
  └─ 增大接收缓冲区

窗口缩放

问题:
  └─ TCP 头窗口字段只有 16 位(最大 64KB)

解决:
  ├─ Window Scale 选项
  ├─ 最大窗口:64KB × 2^14 = 1GB
  └─ 高带宽延迟积网络必需

带宽延迟积(BDP)

计算公式

BDP = 带宽 × RTT

示例:
  带宽 = 100 Mbps = 12.5 MB/s
  RTT = 50ms = 0.05s
  BDP = 12.5 × 0.05 = 0.625 MB = 640 KB

最优缓冲区大小 ≥ BDP

网络瓶颈识别

带宽瓶颈

症状

  • 网卡利用率接近 100%
  • 发送/接收队列满
  • 应用无法达到期望速率

分析

# 查看网卡统计
ip -s link show eth0

# 实时监控
iftop
nload

# 查看带宽使用
sar -n DEV 1

延迟瓶颈

高延迟原因

网络层面:
  ├─ 物理距离远
  ├─ 网络拥塞
  ├─ 路由跳数多
  └─ 丢包重传

系统层面:
  ├─ CPU 处理慢
  ├─ 中断延迟高
  ├─ 内核缓冲区满
  └─ 应用处理慢

测量延迟

# ICMP 延迟
ping -c 10 example.com

# TCP 连接延迟
hping3 -S -p 80 example.com

# 应用层延迟(HTTP)
curl -w "@curl-format.txt" -o /dev/null -s http://example.com

丢包问题

丢包位置

链路丢包:
  ├─ 物理介质问题
  ├─ 网络设备故障
  └─ 带宽过载

内核丢包:
  ├─ 接收队列满
  ├─ 发送队列满
  └─ 防火墙规则

应用丢包:
  ├─ Socket 缓冲区满
  └─ 应用处理慢

检测丢包

# 查看网络统计
netstat -s | grep -i loss
ss -s

# 网卡丢包
ethtool -S eth0 | grep -i drop

# 内核丢包
cat /proc/net/softnet_stat

网络优化策略

内核参数优化

TCP 缓冲区

# 查看当前值
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem

# 优化(单位:字节)
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 格式:min default max

# 自动调整
net.ipv4.tcp_moderate_rcvbuf = 1

连接队列

# SYN 队列(半连接)
net.ipv4.tcp_max_syn_backlog = 8192

# Accept 队列(全连接)
net.core.somaxconn = 1024

# 应用层也需要配置
# Nginx: listen 80 backlog=1024;

TCP 优化

# 启用 TCP Fast Open
net.ipv4.tcp_fastopen = 3

# 启用窗口缩放
net.ipv4.tcp_window_scaling = 1

# 启用时间戳
net.ipv4.tcp_timestamps = 1

# 启用选择性确认(SACK)
net.ipv4.tcp_sack = 1

# FIN_WAIT2 超时
net.ipv4.tcp_fin_timeout = 30

# TIME_WAIT 重用
net.ipv4.tcp_tw_reuse = 1

# keepalive 设置
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 15

拥塞控制算法

# 查看可用算法
sysctl net.ipv4.tcp_available_congestion_control

# 设置算法
net.ipv4.tcp_congestion_control = bbr

# BBR 优势
# ├─ 更高吞吐量
# ├─ 更低延迟
# └─ 适合高延迟网络

网卡优化

Ring Buffer

# 查看当前大小
ethtool -g eth0

# 增加接收队列
ethtool -G eth0 rx 4096

# 增加发送队列
ethtool -G eth0 tx 4096

中断合并

# 查看中断合并设置
ethtool -c eth0

# 减少中断频率
ethtool -C eth0 rx-usecs 50

# 平衡:
# ├─ 高频率:低延迟、高 CPU
# └─ 低频率:高延迟、低 CPU

RSS(Receive Side Scaling)

# 启用多队列
ethtool -L eth0 combined 4

# 查看队列统计
ethtool -S eth0 | grep rx_queue

# 分配中断到不同 CPU
# 提高并行处理能力

TSO/GSO(分段卸载)

# 查看状态
ethtool -k eth0 | grep offload

# 启用 TSO(TCP Segmentation Offload)
ethtool -K eth0 tso on

# 启用 GSO(Generic Segmentation Offload)
ethtool -K eth0 gso on

# 减少 CPU 负载

应用层优化

连接复用

HTTP/1.1 Keep-Alive:
  ├─ 复用 TCP 连接
  ├─ 减少连接建立开销
  └─ 减少 TIME_WAIT

HTTP/2:
  ├─ 多路复用
  ├─ 一个连接多个流
  └─ 头部压缩

负载均衡

策略:
  ├─ Round Robin:轮询
  ├─ Least Connections:最少连接
  ├─ IP Hash:基于源 IP
  └─ 响应时间:选择最快的

CDN 加速

优势:
  ├─ 内容靠近用户
  ├─ 减少延迟
  ├─ 降低源站压力
  └─ 提高可用性

网络性能分析工具

基础工具

netstat/ss

# 显示所有连接
netstat -antp
ss -antp

# 统计信息
netstat -s
ss -s

# 监听端口
netstat -tuln
ss -tuln

# TIME_WAIT 统计
netstat -an | grep TIME_WAIT | wc -l
ss -tan state time-wait | wc -l

ip 命令

# 查看网卡信息
ip addr show
ip link show

# 查看路由
ip route show

# 查看统计
ip -s link show eth0

# 查看邻居(ARP)
ip neigh show

监控工具

iftop

# 实时带宽监控
iftop -i eth0

# 按目的地分组
iftop -i eth0 -P

# 显示端口
iftop -i eth0 -p

sar

# 网络统计
sar -n DEV 1 10      # 设备统计
sar -n EDEV 1 10     # 错误统计
sar -n TCP 1 10      # TCP 统计
sar -n ETCP 1 10     # TCP 错误
sar -n SOCK 1 10     # Socket 使用

nload

# 简洁的带宽监控
nload eth0

# 多网卡
nload eth0 eth1

抓包分析

tcpdump

# 基本抓包
tcpdump -i eth0

# 指定条件
tcpdump -i eth0 port 80
tcpdump -i eth0 host 192.168.1.1
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'

# 保存和读取
tcpdump -i eth0 -w capture.pcap
tcpdump -r capture.pcap

# 详细输出
tcpdump -i eth0 -v
tcpdump -i eth0 -vv
tcpdump -i eth0 -vvv

Wireshark

功能:
  ├─ 图形化界面
  ├─ 协议解析
  ├─ 流量分析
  └─ 统计图表

分析流程:
  1. 捕获数据包
  2. 过滤相关流量
  3. 分析协议细节
  4. 识别问题模式

性能测试

iperf3

# 服务端
iperf3 -s

# 客户端(TCP)
iperf3 -c server_ip -t 60

# UDP 测试
iperf3 -c server_ip -u -b 1G

# 反向测试
iperf3 -c server_ip -R

# 并发流
iperf3 -c server_ip -P 10

# JSON 输出
iperf3 -c server_ip -J

netperf

# 服务端
netserver

# TCP 流测试
netperf -H server_ip -t TCP_STREAM

# TCP 请求响应
netperf -H server_ip -t TCP_RR

# UDP 流测试
netperf -H server_ip -t UDP_STREAM

网络优化案例

案例1:高并发连接

症状

  • TIME_WAIT 连接过多
  • 端口耗尽
  • 新连接失败

优化

# 1. 启用 TIME_WAIT 重用
net.ipv4.tcp_tw_reuse = 1

# 2. 缩短 TIME_WAIT 超时
net.ipv4.tcp_fin_timeout = 30

# 3. 扩大本地端口范围
net.ipv4.ip_local_port_range = 10000 65000

# 4. 增加连接追踪表
net.netfilter.nf_conntrack_max = 1000000

# 5. 应用层使用连接池

案例2:长肥管道(高延迟高带宽)

症状

  • 带宽利用率低
  • 传输速度慢
  • RTT 高(>100ms)

优化

# 1. 增大 TCP 缓冲区
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864

# 2. 启用窗口缩放
net.ipv4.tcp_window_scaling = 1

# 3. 使用 BBR 拥塞控制
net.ipv4.tcp_congestion_control = bbr

# 4. 启用 SACK
net.ipv4.tcp_sack = 1

案例3:网卡丢包

症状

  • ethtool 显示 rx_dropped 增加
  • 应用收包丢失
  • 性能下降

优化

# 1. 增大 Ring Buffer
ethtool -G eth0 rx 4096

# 2. 启用多队列
ethtool -L eth0 combined 4

# 3. 调整中断亲和性
echo "f" > /proc/irq/<IRQ>/smp_affinity

# 4. 增大内核缓冲区
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216

# 5. 启用 RPS/RFS
echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus

案例4:DNS 解析慢

症状

  • 应用启动慢
  • 首次请求延迟高
  • getaddrinfo 耗时长

优化

# 1. 使用本地 DNS 缓存
# 安装 nscd 或 dnsmasq

# 2. 优化 /etc/resolv.conf
options timeout:1 attempts:2 rotate

# 3. 使用多个 DNS 服务器
nameserver 8.8.8.8
nameserver 1.1.1.1

# 4. 应用层缓存 DNS 结果

# 5. 考虑使用异步 DNS 解析

网络安全与性能

防火墙优化

iptables 性能

# 规则优化
# ├─ 最常匹配的规则放前面
# ├─ 使用 ipset 替代大量规则
# └─ 减少规则数量

# ipset 示例
ipset create blocked_ips hash:ip
ipset add blocked_ips 192.168.1.1
iptables -A INPUT -m set --match-set blocked_ips src -j DROP

# 连接追踪
# ├─ 增大表大小
net.netfilter.nf_conntrack_max = 1000000
# ├─ 减少超时
net.netfilter.nf_conntrack_tcp_timeout_established = 600

DDoS 防护

SYN Flood 防护

# SYN Cookies
net.ipv4.tcp_syncookies = 1

# SYN 队列大小
net.ipv4.tcp_max_syn_backlog = 8192

# SYN-ACK 重试次数
net.ipv4.tcp_synack_retries = 2

连接限制

# iptables 限速
iptables -A INPUT -p tcp --dport 80 \
  -m connlimit --connlimit-above 20 -j REJECT

# 限制新连接速率
iptables -A INPUT -p tcp --dport 80 \
  -m recent --set --name HTTP
iptables -A INPUT -p tcp --dport 80 \
  -m recent --update --seconds 60 --hitcount 20 \
  --name HTTP -j DROP

总结:网络性能优化需要从协议栈各层入手,理解原理,结合监控数据,系统性地分析和优化。

下一章:学习 安全加固 章节。