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:技能图谱

第9章 流量控制与QoS

学习目标

  • 理解qdisc(队列规则)的工作原理
  • 掌握TC(Traffic Control)工具的使用
  • 了解HTB、fq_codel等调度算法
  • 能够配置和调优网络QoS

🔬 原理

qdisc(队列规则)

qdisc类型:

  • pfifo_fast:默认,3个优先级队列
  • fq_codel:公平队列,主动队列管理
  • HTB:分层令牌桶,复杂带宽分配
  • TBF:令牌桶过滤器,简单限速

HTB(Hierarchical Token Bucket)

HTB特点:

  • 分层限速
  • 带宽借用
  • 优先级控制

HTB结构:

root (100Mbps)
├── class1:1 (50Mbps)
│   ├── class1:10 (30Mbps)
│   └── class1:20 (20Mbps)
└── class1:2 (50Mbps)

fq_codel算法

fq_codel特点:

  • 按流隔离
  • 主动队列管理
  • 控制延迟

算法原理:

  1. 按流哈希分组
  2. 轮询调度各流
  3. 检测队列延迟
  4. 主动丢弃包

️ 实现

qdisc实现

struct Qdisc {
    struct Qdisc_ops *ops;
    struct net_device *dev;
    struct sk_buff_head q;
    struct gnet_stats_basic_packed bstats;
    struct gnet_stats_queue qstats;
    unsigned long state;
    struct sk_buff *gso_skb;
    u32 handle;
    u32 parent;
    int (*enqueue)(struct sk_buff *skb, struct Qdisc *sch);
    struct sk_buff *(*dequeue)(struct Qdisc *sch);
    // ... 更多字段
};

HTB实现

struct htb_class {
    struct Qdisc_class_common common;
    struct psched_ratecfg rate;
    struct psched_ratecfg ceil;
    s64 buffer, cbuffer;
    s64 mbuffer;
    struct htb_class *parent;
    struct htb_class *inner;
    struct htb_class *leaf;
    struct Qdisc *q;
    struct tcf_proto *filter_list;
    struct htb_class *next;
    // ... 更多字段
};

🛠️ 命令

TC命令

# 查看qdisc
tc qdisc show dev eth0

# 添加qdisc
sudo tc qdisc add dev eth0 root htb default 12

# 删除qdisc
sudo tc qdisc del dev eth0 root

# 查看class
tc class show dev eth0

# 添加class
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit

限速配置

# TBF限速
sudo tc qdisc add dev eth0 root tbf rate 10mbit burst 32kbit latency 400ms

# HTB限速
sudo tc qdisc add dev eth0 root handle 1: htb default 12
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 100mbit

代码

简单限速程序

// simple_tc.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("socket");
        return 1;
    }
    
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(8080),
        .sin_addr.s_addr = INADDR_ANY
    };
    
    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        perror("bind");
        close(sock);
        return 1;
    }
    
    if (listen(sock, 128) < 0) {
        perror("listen");
        close(sock);
        return 1;
    }
    
    printf("Server listening on port 8080\n");
    
    while (1) {
        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        
        int client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_len);
        if (client_sock < 0) {
            perror("accept");
            continue;
        }
        
        // 简单限速:每次发送1KB,间隔1ms
        char buffer[1024];
        memset(buffer, 'A', sizeof(buffer));
        
        for (int i = 0; i < 1000; i++) {
            if (send(client_sock, buffer, sizeof(buffer), 0) < 0) {
                perror("send");
                break;
            }
            usleep(1000); // 1ms延迟
        }
        
        close(client_sock);
    }
    
    close(sock);
    return 0;
}

编译运行:

gcc simple_tc.c -o simple_tc
./simple_tc

🧪 实验

实验1:TBF限速测试

目标:测试TBF限速效果

步骤:

# 1. 查看当前qdisc
tc qdisc show dev eth0

# 2. 添加TBF限速
sudo tc qdisc add dev eth0 root tbf rate 10mbit burst 32kbit latency 400ms

# 3. 测试限速效果
iperf3 -s &
iperf3 -c localhost -t 30

# 4. 删除限速
sudo tc qdisc del dev eth0 root

# 5. 对比测试
iperf3 -c localhost -t 30

预期结果:

  • 理解TBF限速原理
  • 观察限速效果
  • 掌握TBF配置

实验2:HTB分层限速

目标:配置HTB分层限速

步骤:

# 1. 添加HTB qdisc
sudo tc qdisc add dev eth0 root handle 1: htb default 12

# 2. 添加根class
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit

# 3. 添加子class
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 100mbit
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 30mbit ceil 50mbit

# 4. 添加过滤器
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:10
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip dport 443 0xffff flowid 1:20

# 5. 测试效果
iperf3 -s -p 80 &
iperf3 -s -p 443 &
iperf3 -c localhost -p 80 -t 30
iperf3 -c localhost -p 443 -t 30

预期结果:

  • 理解HTB分层结构
  • 观察带宽分配
  • 掌握HTB配置

实验3:fq_codel测试

目标:测试fq_codel公平队列

步骤:

# 1. 添加fq_codel qdisc
sudo tc qdisc add dev eth0 root fq_codel

# 2. 测试多流公平性
for i in {1..5}; do
    iperf3 -c localhost -t 30 &
done
wait

# 3. 查看统计信息
tc -s qdisc show dev eth0

预期结果:

  • 理解fq_codel算法
  • 观察公平性
  • 掌握fq_codel配置

排错

常见问题排查

问题1:qdisc不生效

# 检查qdisc配置
tc qdisc show dev eth0

# 检查class配置
tc class show dev eth0

# 检查过滤器
tc filter show dev eth0

问题2:限速不准确

# 检查限速参数
tc class show dev eth0

# 调整限速参数
sudo tc class change dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 100mbit

# 测试限速效果
iperf3 -c localhost -t 30

问题3:性能问题

# 检查qdisc统计
tc -s qdisc show dev eth0

# 检查丢包情况
tc -s class show dev eth0

# 优化qdisc参数
sudo tc qdisc change dev eth0 root fq_codel limit 1000

排错清单

  • [ ] 检查qdisc配置(tc qdisc show)
  • [ ] 验证class配置(tc class show)
  • [ ] 确认过滤器规则(tc filter show)
  • [ ] 测试限速效果(iperf3、netperf)
  • [ ] 查看统计信息(tc -s)
  • [ ] 检查网络连通性(ping、telnet)
  • [ ] 查看系统日志(dmesg、/var/log/syslog)
Prev
第8章 Netfilter与防火墙