HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 网络架构师学习手册

    • 网络架构师学习教程
    • 基础篇

      • 第1章 网络模型与数据流转
      • 第2章 以太网与二层通信
      • 第3章 IP路由与三层转发
      • 第4章 TCP与可靠传输
      • 第5章 应用层协议
    • Linux网络栈

      • 第6章 数据包接收路径
      • 第7章 多核网络优化
      • 第8章 Netfilter与防火墙
      • 第9章 流量控制与QoS
    • 虚拟网络

      • 第10章 Network Namespace基础
      • 第11章 Bridge与互联
      • 第12章 VXLAN与Overlay网络
      • 第13章 OVS与SDN
    • Kubernetes网络

      • 第14章 CNI模型与实现
      • 第15章 kube-proxy与Service实现
      • 第16章 CoreDNS与服务发现
      • 第17章 NetworkPolicy与安全隔离
      • 第18章 Calico网络深度解析
      • 第19章 Cilium与eBPF网络
    • 网络架构

      • 第20章 网络设备与拓扑设计
      • 第21章 网络容量规划与计算
      • 第22章 负载均衡架构设计
      • 第23章 高可用网络架构
      • 第24章 网络安全架构
    • 性能调优

      • 第25章 系统级网络调优
      • 第26章 故障排查方法论
      • 第27章 生产环境案例分析
    • 前沿技术

      • 第28章 eBPF深度实践
      • 第29章 ServiceMesh与边车代理
      • 第30章 网络技术趋势与未来展望
    • 附录

      • 附录A:命令速查手册
      • 附录B:排错决策树
      • 附录C:学习资源
      • 附录D:技能图谱

第25章 系统级网络调优

学习目标

  • 掌握Linux网络参数调优技术
  • 了解网卡中断和队列优化
  • 掌握零拷贝和io_uring技术
  • 能够进行网络性能调优

前置知识

  • 第24章:安全架构
  • 第6章:数据包接收路径
  • 第7章:多核网络优化

25.1 网络参数调优

25.1.1 TCP参数优化

1. 缓冲区大小

# 设置TCP缓冲区大小
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_rmem = 4096 87380 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_wmem = 4096 65536 134217728' >> /etc/sysctl.conf

# 应用配置
sysctl -p

2. 连接参数

# 设置连接参数
echo 'net.ipv4.tcp_keepalive_time = 600' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_keepalive_intvl = 60' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_keepalive_probes = 3' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 8192' >> /etc/sysctl.conf
echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf

# 应用配置
sysctl -p

3. 拥塞控制

# 设置拥塞控制算法
echo 'net.ipv4.tcp_congestion_control = bbr' >> /etc/sysctl.conf

# 查看可用算法
cat /proc/sys/net/ipv4/tcp_available_congestion_control

# 查看当前算法
cat /proc/sys/net/ipv4/tcp_congestion_control

25.1.2 UDP参数优化

1. UDP缓冲区

# 设置UDP缓冲区
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.udp_rmem_min = 8192' >> /etc/sysctl.conf
echo 'net.ipv4.udp_wmem_min = 8192' >> /etc/sysctl.conf

# 应用配置
sysctl -p

2. UDP队列

# 设置UDP队列大小
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
echo 'net.core.netdev_budget = 600' >> /etc/sysctl.conf

# 应用配置
sysctl -p

25.1.3 网络接口参数

1. 接口队列

# 设置接口队列
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
echo 'net.core.netdev_budget = 600' >> /etc/sysctl.conf
echo 'net.core.netdev_budget_usecs = 5000' >> /etc/sysctl.conf

# 应用配置
sysctl -p

2. 接口缓冲区

# 设置接口缓冲区
echo 'net.core.rmem_default = 262144' >> /etc/sysctl.conf
echo 'net.core.wmem_default = 262144' >> /etc/sysctl.conf
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf

# 应用配置
sysctl -p

25.2 网卡优化

25.2.1 网卡队列配置

1. 多队列配置

# 查看网卡队列数
ethtool -l eth0

# 设置网卡队列数
ethtool -L eth0 combined 8

# 查看队列配置
ethtool -l eth0

2. 队列权重

# 设置队列权重
echo 1 > /sys/class/net/eth0/queues/rx-0/rps_cpus
echo 2 > /sys/class/net/eth0/queues/rx-1/rps_cpus
echo 4 > /sys/class/net/eth0/queues/rx-2/rps_cpus
echo 8 > /sys/class/net/eth0/queues/rx-3/rps_cpus

25.2.2 网卡中断优化

1. 中断绑定

# 查看中断分布
cat /proc/interrupts | grep eth0

# 绑定中断到特定CPU
echo 2 > /proc/irq/24/smp_affinity
echo 4 > /proc/irq/25/smp_affinity
echo 8 > /proc/irq/26/smp_affinity
echo 16 > /proc/irq/27/smp_affinity

2. 中断合并

# 启用中断合并
ethtool -C eth0 rx-usecs 100
ethtool -C eth0 tx-usecs 100
ethtool -C eth0 rx-frames 32
ethtool -C eth0 tx-frames 32

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

25.2.3 网卡特性优化

1. 硬件卸载

# 启用硬件卸载
ethtool -K eth0 gro on
ethtool -K eth0 gso on
ethtool -K eth0 tso on
ethtool -K eth0 ufo on

# 查看网卡特性
ethtool -k eth0

2. 网卡缓冲区

# 设置网卡缓冲区
ethtool -G eth0 rx 4096
ethtool -G eth0 tx 4096

# 查看网卡缓冲区
ethtool -g eth0

25.3 零拷贝技术

25.3.1 零拷贝原理

传统数据拷贝:

用户空间 ←→ 内核空间 ←→ 网卡
    ↓         ↓
  应用缓冲区  内核缓冲区

零拷贝:

用户空间 ←→ 网卡
    ↓
  应用缓冲区

25.3.2 零拷贝实现

1. sendfile系统调用

#include <sys/sendfile.h>

// 使用sendfile实现零拷贝
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

// 示例代码
int in_fd = open("input.txt", O_RDONLY);
int out_fd = socket(AF_INET, SOCK_STREAM, 0);
sendfile(out_fd, in_fd, NULL, file_size);

2. splice系统调用

#include <fcntl.h>

// 使用splice实现零拷贝
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

// 示例代码
int pipefd[2];
pipe(pipefd);
splice(in_fd, NULL, pipefd[1], NULL, len, SPLICE_F_MOVE);
splice(pipefd[0], NULL, out_fd, NULL, len, SPLICE_F_MOVE);

3. mmap系统调用

#include <sys/mman.h>

// 使用mmap实现零拷贝
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

// 示例代码
void *mapped = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, in_fd, 0);
send(out_fd, mapped, file_size, 0);
munmap(mapped, file_size);

25.3.3 零拷贝应用

1. Nginx零拷贝

# 启用sendfile
sendfile on;
tcp_nopush on;
tcp_nodelay on;

# 启用sendfile
location / {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
}

2. Apache零拷贝

# 启用sendfile
EnableSendfile On

# 启用mmap
EnableMMAP On

25.4 io_uring技术

25.4.1 io_uring概述

io_uring是Linux 5.1引入的异步I/O接口,提供高性能的异步I/O操作。

特点:

  • 异步I/O操作
  • 零拷贝支持
  • 批量操作
  • 高性能

25.4.2 io_uring实现

1. 基本使用

#include <liburing.h>

// 创建io_uring实例
struct io_uring ring;
io_uring_queue_init(32, &ring, 0);

// 准备异步操作
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
io_uring_prep_read(sqe, fd, buffer, size, offset);

// 提交操作
io_uring_submit(&ring);

// 等待完成
struct io_uring_cqe *cqe;
io_uring_wait_cqe(&ring, &cqe);
io_uring_cqe_seen(&ring, cqe);

2. 网络I/O

// 异步网络I/O
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
io_uring_prep_send(sqe, sockfd, buffer, size, 0);
io_uring_submit(&ring);

3. 批量操作

// 批量提交多个操作
for (int i = 0; i < 10; i++) {
    struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
    io_uring_prep_read(sqe, fd, buffer[i], size, offset[i]);
}
io_uring_submit(&ring);

25.4.3 io_uring应用

1. 高性能Web服务器

// 使用io_uring实现高性能Web服务器
#include <liburing.h>

int main() {
    struct io_uring ring;
    io_uring_queue_init(1024, &ring, 0);
    
    // 处理连接
    while (1) {
        struct io_uring_cqe *cqe;
        io_uring_wait_cqe(&ring, &cqe);
        
        // 处理完成的事件
        handle_completion(cqe);
        io_uring_cqe_seen(&ring, cqe);
    }
}

2. 高性能文件传输

// 使用io_uring实现高性能文件传输
#include <liburing.h>

int transfer_file(int in_fd, int out_fd, size_t size) {
    struct io_uring ring;
    io_uring_queue_init(32, &ring, 0);
    
    char buffer[4096];
    size_t transferred = 0;
    
    while (transferred < size) {
        struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
        io_uring_prep_read(sqe, in_fd, buffer, sizeof(buffer), transferred);
        io_uring_submit(&ring);
        
        struct io_uring_cqe *cqe;
        io_uring_wait_cqe(&ring, &cqe);
        
        if (cqe->res > 0) {
            transferred += cqe->res;
            // 写入输出文件
            write(out_fd, buffer, cqe->res);
        }
        
        io_uring_cqe_seen(&ring, cqe);
    }
    
    return transferred;
}

25.5 实验:网络性能调优

25.5.1 实验环境

环境要求:

  • 两台Linux主机
  • 网络互通
  • 支持iperf3

网络拓扑:

┌─────────────────────────────────────────────────────────────┐
│                    Performance Lab                         │
├─────────────────────────────────────────────────────────────┤
│  Client                                                    │
│      │                                                     │
│  ┌──────┐                                                 │
│  │ Server │                                                │
│  └───────┘                                                 │
└─────────────────────────────────────────────────────────────┘

25.5.2 实验步骤

步骤1:基线测试

# 在服务器上启动iperf3
iperf3 -s

# 在客户端上测试
iperf3 -c server-ip -t 60 -i 10

步骤2:TCP参数优化

# 在服务器上优化TCP参数
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_rmem = 4096 87380 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_wmem = 4096 65536 134217728' >> /etc/sysctl.conf
sysctl -p

# 重新测试
iperf3 -c server-ip -t 60 -i 10

步骤3:网卡优化

# 优化网卡队列
ethtool -L eth0 combined 8

# 优化网卡中断
echo 2 > /proc/irq/24/smp_affinity
echo 4 > /proc/irq/25/smp_affinity

# 重新测试
iperf3 -c server-ip -t 60 -i 10

步骤4:零拷贝测试

# 使用零拷贝传输文件
# 创建大文件
dd if=/dev/zero of=testfile bs=1M count=1000

# 使用scp传输
time scp testfile user@client-ip:/tmp/

# 使用rsync传输
time rsync -av testfile user@client-ip:/tmp/

25.6 性能监控

25.6.1 系统监控

1. 网络统计

# 查看网络统计
cat /proc/net/dev

# 查看TCP统计
cat /proc/net/tcp

# 查看UDP统计
cat /proc/net/udp

2. 中断统计

# 查看中断统计
cat /proc/interrupts

# 查看软中断统计
cat /proc/softirqs

3. 内存统计

# 查看内存统计
cat /proc/meminfo

# 查看网络内存使用
cat /proc/slabinfo | grep skb

25.6.2 性能分析

1. 使用perf分析

# 安装perf
apt-get install linux-tools-common linux-tools-generic

# 分析网络性能
perf record -e net:net_dev_xmit,net:net_dev_receive -a sleep 10
perf report

2. 使用bcc分析

# 安装bcc
apt-get install bpfcc-tools

# 分析网络延迟
tcpaccept -p $(pgrep nginx)

# 分析网络吞吐量
tcptop

25.7 故障排查

25.7.1 常见问题诊断

问题1:网络延迟高

# 检查网络延迟
ping -c 100 8.8.8.8

# 检查网络队列
tc -s qdisc show dev eth0

# 检查网络缓冲区
cat /proc/sys/net/core/rmem_max
cat /proc/sys/net/core/wmem_max

问题2:网络吞吐量低

# 检查网卡状态
ethtool eth0

# 检查网卡队列
ethtool -l eth0

# 检查中断分布
cat /proc/interrupts | grep eth0

问题3:CPU使用率高

# 检查CPU使用率
top
htop

# 检查软中断
cat /proc/softirqs

# 检查网络处理
perf top

25.7.2 排错工具

# 使用iftop监控网络
iftop -i eth0

# 使用nload监控网络
nload eth0

# 使用tcpdump抓包
tcpdump -i eth0 -n

# 使用netstat查看连接
netstat -tuln

25.8 排错清单

25.8.1 性能调优检查

  • [ ] TCP参数是否优化
  • [ ] 网卡队列是否配置
  • [ ] 中断是否绑定
  • [ ] 零拷贝是否启用
  • [ ] 监控是否正常

25.8.2 性能问题检查

  • [ ] 网络延迟是否正常
  • [ ] 吞吐量是否满足要求
  • [ ] CPU使用率是否正常
  • [ ] 内存使用是否正常
  • [ ] 错误率是否正常

25.9 延伸阅读

  • Linux Network Performance Tuning
  • Zero Copy I/O
  • io_uring Documentation
  • BPF Performance Tools

下一章:第26章 故障排查方法论

返回目录:README

Next
第26章 故障排查方法论