4. 队列调度与拥塞管理:FIFO、PQ、WFQ、CBWFQ原理,在边缘网关上的配置实践

好,咱们接着聊。上一节我们讲了流量标记和 policing,说白了就是给数据包打上标签,然后决定是放行还是丢弃。但光有这些还不够——当多个数据流挤在一个出口时,谁先走谁后走?这就引出了队列调度的问题。

我个人习惯把队列调度比作「十字路口的红绿灯」。没有调度,大家一窝蜂冲出去,结果就是堵死。边缘网关上的情况更复杂,因为出口带宽通常很有限,而接入的设备五花八门。你想想看,如果视频监控流和办公网页流抢带宽,谁更重要?

嗯,今天我们就来拆解四种最常见的队列调度算法:FIFO、PQ、WFQ、CBWFQ。我会结合我在边缘网关项目中的实际配置经验来讲。

4.1 FIFO:最简单的,也是最粗暴的

FIFO,全称 First In First Out,先进先出。这玩意儿没什么技术含量——数据包按到达顺序排队,先来的先走。

优点:实现简单,CPU 开销几乎为零。

缺点:没有任何优先级区分。如果一个大文件下载占满了队列,语音包就得在后面乖乖等着。结果就是——语音卡顿、视频花屏。

⚠ 注意:我在项目中见过不少小厂家的边缘网关,默认就是 FIFO。客户投诉说「视频老是卡」,一查,原来是 FIFO 队列里混着 P2P 下载流。所以,但凡有点 QoS 要求的场景,千万别用 FIFO。

4.2 PQ:给重要流量开绿灯

PQ,Priority Queuing,优先级队列。它的思路很简单:把流量分成高、中、低优先级。高优先级的包永远先走,低优先级的包只有高优先级队列空了才能走。

工作原理

  • 通常有 4 个队列:High、Medium、Normal、Low
  • 调度器先看 High 队列,有包就发,直到空
  • 再看 Medium,以此类推

听起来很完美对吧?但有个致命问题——饥饿。如果高优先级流量一直有包,低优先级队列可能永远得不到服务。我曾经在一个视频监控项目里遇到过:客户把视频流设为最高优先级,结果视频流一跑起来,其他业务全部瘫痪,连 SSH 登录都进不去。

💡 我的建议:PQ 适合用在「关键流量极少且可控」的场景。比如只把 VoIP 信令或工业控制报文设为高优先级,其他流量走低优先级。但一定要配合限速使用,防止高优先级流量泛滥。

4.3 WFQ:公平但不绝对

WFQ,Weighted Fair Queuing,加权公平队列。它解决了 PQ 的饥饿问题,但引入了「权重」的概念。

说白了,WFQ 会为每个流(按源/目的 IP、端口等五元组)自动创建一个队列。然后根据流的数量动态分配带宽。流越多,每个流分到的带宽越少。但权重高的流,分到的比例更大。

关键特性

  • 自动分类:不需要手动配置分类规则
  • 公平性:每个流至少能分到一点带宽
  • 权重可调:但调整粒度较粗

我记得有一次在工厂边缘网关调试,现场有 30 多台 PLC 同时上报数据。用 WFQ 后,每台 PLC 都能分到差不多的带宽,没有出现某台设备被饿死的情况。但问题在于——WFQ 对实时性要求高的流量(比如语音)支持不够好,因为它还是尽量追求公平。

4.4 CBWFQ:最灵活的生产力工具

CBWFQ,Class-Based Weighted Fair Queuing,基于类的加权公平队列。这是目前边缘网关上最常用的调度方式。

它的核心思想是:你先定义好流量分类(比如语音类、视频类、数据类),然后为每个类指定带宽保证和队列深度。调度器在类之间使用加权公平调度,类内部可以使用 FIFO 或 WFQ。

配置示例(华为 AR 系列边缘网关)

#
# 定义流量分类
traffic classifier voice
 if-match dscp ef
#
traffic classifier video
 if-match dscp af41
#
traffic classifier data
 if-match dscp 0
#

# 定义行为
traffic behavior voice
 queue ef bandwidth 30%  # 保证 30% 带宽,可借用
#
traffic behavior video
 queue af bandwidth 40%  # 保证 40% 带宽
#
traffic behavior data
 queue be bandwidth 30%  # 尽力而为
#

# 应用策略
qos policy CBWFQ_POLICY
 classifier voice behavior voice
 classifier video behavior video
 classifier data behavior data
#

# 在接口上应用
interface GigabitEthernet0/0/1
 qos policy CBWFQ_POLICY outbound
🔑 关键点:CBWFQ 允许你为每个类指定「保证带宽」和「最大带宽」。保证带宽是底线,最大带宽是上限。如果某个类没用完带宽,其他类可以借用——这就是「可借用」的含义。

4.5 边缘网关上的配置实践

好了,理论讲完了。咱们来点实际的。我在多个边缘计算项目中总结了一套配置思路,分享给你。

第一步:分析流量模型

先搞清楚你的边缘网关上跑的是什么流量。我一般会抓包 24 小时,统计出流量占比:

流量类型 典型占比 延迟要求 推荐队列
VoIP / 视频会议 5-10% < 150ms EF(加速转发)
工业控制(Modbus TCP) 1-5% < 50ms AF4(确保转发)
视频监控流 40-60% < 500ms AF3
普通上网 / 文件下载 20-40% 尽力而为 BE(默认)

第二步:配置 CBWFQ 策略

我建议用 CBWFQ 作为主力调度方式。上面给的华为配置示例可以直接套用,但要注意几点:

  • 保证带宽总和不要超过 100%,留 10-20% 给控制平面和未知流量
  • 语音类用 EF 队列,严格优先,但一定要限速(比如不超过总带宽的 30%)
  • 视频类用 AF 队列,保证带宽,允许借用
  • 数据类用 BE 队列,尽力而为
⚠ 避坑指南:我曾经在一个项目中,把语音类的 EF 队列带宽设成了 50%,结果语音流一多,其他业务全部被挤死。后来我学乖了——EF 队列一定要设上限,建议不超过 30%。另外,别忘了在入方向也做 policing,防止非法流量直接打满队列。

第三步:调整队列深度

队列深度(Queue Length)也很关键。太浅了容易丢包,太深了延迟大。我一般这样设:

  • 语音队列:深度 64 包,延迟敏感,丢包比延迟更可怕
  • 视频队列:深度 128-256 包,允许一定抖动
  • 数据队列:深度 512-1024 包,可以容忍较大延迟

第四步:验证与调优

配置完别急着走。用 iperf 打流测试,同时跑一个语音模拟器。观察延迟和丢包率。我习惯用 display qos queue statistics 命令看每个队列的丢包情况。如果某个队列丢包率超过 1%,就该调整带宽分配了。

4.6 总结一下

四种调度算法,各有各的脾气:

  • FIFO:简单但无能,只适合实验室或低负载场景
  • PQ:给关键流量开绿灯,但小心饿死其他流量
  • WFQ:公平但不够灵活,适合流量种类多的场景
  • CBWFQ:最推荐,灵活可控,适合边缘网关的复杂环境

最后说一句:队列调度不是一劳永逸的事。网络流量是动态的,今天视频流占 40%,明天可能变成 60%。我建议每季度 review 一次 QoS 策略,根据实际流量变化做调整。嗯,这就是我在边缘网关上的实战经验,希望对你有帮助。