做网络项目这么多年,处理过的QOS需求里,十个有八个是同一句话:“视频会议卡、语音听不清,把流量优先保障一下。”可真要动手配置,第一步压根不是调队列、设带宽,而是先把报文分清楚——哪些是语音、哪些是视频、哪些是普通下载。这篇是QOS实操系列的第二篇,专门聊透“报文简单分类和标记”这个环节:基于报文里自带的标签字段,用最快的速度把流量分类,再打上统一的标记,为后面做队列调度铺路。适合正在配交换机QOS、想在真实设备上落地分类策略的兄弟们参考。
1. QOS分类与标记的整体设计思路
1.1 为什么要给报文“分门别类”
先想清楚一个底层问题:网络设备在转发报文时,底层逻辑其实很“一根筋”——有队列就往队列里塞,队列满了就丢包,调度器按顺序出队。如果不做任何分类,所有流量共享同一个转发行为,那语音、视频和下载任务在设备看来是平等的,拥塞时大家一起丢包、一起排队。问题就来了:语音丢几个包就听不清,视频卡一下画面就糊,而下载文件哪怕延迟几秒用户也没啥感觉。
QOS的核心思想就是打破这种“平等”,让不同报文享受差异化服务。要实现差异化,第一步就是识别出“谁是谁”,这一步叫分类。分类的结果决定了报文之后进哪个队列、享受多少带宽、丢包概率是高是低。如果分类错了,后面所有QOS策略都等于白配,甚至可能把重要流量分错队造成反效果。所以分类是整个QOS体系的“地基”。
1.2 分类和标记在QOS整个体系里的位置
完整的QOS处理链路一般是这样的:报文进入设备,先做分类和标记,再进入拥塞管理(排队和调度),同时可能配合拥塞避免(WRED)、流量监管和整形。分类和标记通常在入方向完成,也就是设备刚收到报文的那个接口上就做判断;而排队、调度、丢弃策略一般在出方向生效。
这里有个容易忽略的点:分类是“识别”,标记是“改写”,两者经常连着用,但动作不同。分类识别出流量类别后,设备可以把这层身份用某种方式“写”在报文里,这就是标记。为什么要再写一遍?因为报文可能在网络里多跳转发,每一跳设备都要知道这包是什么优先级。如果只在第一跳设备内部存一个状态,到了下一跳设备就“失忆”了。所以最佳实践是一开始就把身份写进报文的ToS字段或VLAN优先级字段,让后续所有设备都能识别。
1.3 简单分类 vs 复杂分类,先想清楚再动手
分类可以做得非常复杂:按五元组精准匹配、按应用层协议识别、甚至结合用户身份做控制。但实际项目中,我绝大多数情况下只推荐先做“简单分类”——直接读报文里已有的优先级字段(802.1p、DSCP、IP优先级)进行匹配和标记,最多再配上几条ACL按网段区分。
简单分类最大的优势是快且稳。交换机硬件里通常有专门的优先级映射表,一条命令就能把DSCP识别出来,不消耗复杂的ACL资源,转发延迟也低。而复杂分类(比如深度包检测、按应用特征识别)需要额外的硬件表项和计算资源,中低端设备跑起来经常性能吃紧。我对团队的要求是:能用字段解决的就不上DPI,能用网段分清的就不配一大堆ACL。这不是偷懒,是让方案在真实网络里能扛住流量。
2. 报文中那些“自带标签”的字段详解
2.1 二层:802.1p优先级字段
先看二层。在VLAN封装里,802.1Q标签的Tag Control Information(TCI)中有3个bit专门用来做优先级,这就是802.1p,取值0到7。802.1p是QOS最早也最常见的标记方式之一,在接入交换机、局域网内用得非常多。比如常见的语音话机接在接入交换机上,话机发出的报文会在VLAN标签里带上802.1p=5或6,交换机一看这个值就知道这是语音流量。
802.1p取值对应的默认语义大致是:7给网络控制报文,6给时延敏感度极高的语音,5给交互式视频,4给受控负载,3是“尽力转发”的加强版,0是普通尽力而为,1、2保留或给后台业务。当然厂商默认映射不完全一样,但大方向一致。配置设备时我会特别注意:如果把端口设为“信任802.1p”,交换机就会按这个值做后续调度;如果不信任,所有报文都会被重新打为默认的0或接口指定值。
2.2 三层:IP优先级与DSCP
到了三层,QOS标记字段在IP报文头里。老一代叫ToS(Type of Service)字段,一共8bit,其中高3位是IP优先级(IP Precedence),取值0到7;后来RFC 2474定义了DSCP,占用ToS字段的高6位,取值0到63,剩下2bit保留给ECN(显式拥塞通知)。所以你在抓包软件里看到的“Differentiated Services Field”,其实是同一个字节,只是被重新切分了解读。
这里有个常见误区:DSCP和IP优先级并不等价。IP优先级只有8个等级,DSCP有64个编码,其中不仅包含等级还包括“丢弃优先级”。比如AF41(转发保障类,等级4,低丢弃)和AF42(同一等级、中丢弃)…… DSCP更精细,现代网络设备基本都以DSCP作为分类和标记的基准。配置时我一般直接推荐统一改用DSCP,避免后续还要做字段映射的麻烦。
2.3 一张表看懂各字段映射
实际操作里经常要“换算”字段,我把常用的优先级和DSCP值整理成一张对照表,方便直接参考:
| 用途 | 802.1p | IP优先级 | DSCP名称 | DSCP数值 | 抓包显示 |
|---|---|---|---|---|---|
| 尽力而为 | 0 | 0 | BE/CS0 | 0 | 0x00 |
| 语音 | 6 | 5 | EF | 46 | 0xB8 |
| 交互式视频 | 5 | 4 | AF41 | 34 | 0x88 |
| 广播视频 | 5 | 4 | AF31/AF32/AF33 | 26/28/30 | 0x68/0x70/0x78 |
| 信令(如SIP) | 3 | 3 | CS3 | 24 | 0x60 |
| 网络控制 | 7 | 6 | CS6 | 48 | 0xC0 |
| 关键业务数据 | 3~4 | 3~4 | AF21/AF31 | 18/26 | 0x48/0x68 |
| 大量下载/后台 | 1 | 1 | CS1 | 8 | 0x20 |
实际项目中我会按这张表来制定标记标准,并把它写进网络设计文档。好处是全网统一口径:语音就是DSCP EF、交互视频就是AF41,不管中间经过多少台设备,所有人都按这个规则配置,QOS策略就不会出现前后矛盾。
2.4 隧道封装后标签去哪了
简单分类里最容易被坑的就是隧道场景。GRE、VXLAN、IPSec这类技术会在原始报文外面再加一个外层IP头,而大多数网络设备做QOS分类时只看最外层的报文头。如果外层IP头里的DSCP被复制了内层值,那中间路径还能识别;如果外层DSCP被清成0或重置,内层打好的标记在隧道中间根本看不见。
我在一个跨园区传输项目里就踩过:业务系统在报文二层已经打了802.1p高优先级,但流量走到GRE隧道后,中间路由器完全认不出来,视频照样卡。后来解决方法是先确认隧道封装模式对DSCP的处理策略,必要时在隧道出接口上配置标记动作,把关键业务重新标成对应DSCP。所以做分类标记方案时,一定要先画清楚报文在各段路径上的封装形态,否则中间的标记可能只是“自嗨”。
3. 标记动作的核心原理
3.1 标记的本质是改写字段
标记动作听起来很高端,其实关键就是“改字段”。比如设备收到一个DSCP=0的普通数据包,想让它享受高优先级,可以在入方向重写报文的DSCP为EF,这样后续节点看到这个包就知道要优先处理。同理,也可以重写802.1p、MPLS EXP等字段。
不过要分清“信任”和“重标记”:信任模式是说“我认你带来的优先级”,报文保留原样,内部调度直接用这个值;重标记则是“不管原来是什么,到我这按我的规则统一改写”。完整的QOS方案里往往是两者结合:靠近终端侧的设备会重新标记,保证进入骨干网的报文都带着统一标准的标签;骨干设备则做信任,快速读取字段并根据优先级调度。这种分工能让全网标记规则一致,又不会给核心设备增加过多处理压力。
3.2 EF / AF / CS / BE 到底怎么选
标记时必须回答“给我的业务标成什么值”。这里我强烈建议采用RFC 4594的推荐标准,既规范又方便后期维护:
- 实时语音用EF,DSCP=46。EF的语义是低延迟、低抖动、低丢包,专门给语音这类最敏感的业务。
- 交互式视频(视频会议)用AF41,DSCP=34。视频比语音容忍度高一点,但也需要保障,AF41给的是“高优先级、低丢弃”。
- 信令流量用CS3,DSCP=24。信令本身不大但非常关键,SIP协商包丢了,通话根本建立不起来。
- 关键业务数据用AF21/AF31,保证带宽和较低丢包。
- 普通上网、下载用BE,DSCP=0。
很多新手喜欢图省事全标成EF,这是大忌。EF在队列调度中通常进PQ(优先级队列),如果大量高带宽流量都进PQ,拥塞时PQ排队过长,语音反而跟着遭殃。所以EF只给语音,视频用AF类,各司其职,才是合理的标记策略。
3.3 信任模式决定“认不认”报文的标签
配置标记前一定要检查接口的信任模式。很多网络设备默认行为是不信任任何优先级,也就是说哪怕终端发出的报文带了DSCP EF,交换机也会按普通流量处理,这在接入层尤其常见。不信任模式的意义在于防止终端用户乱打标签“插队”,让网络管理员统一控制。
如果你的终端是可控的(比如IP话机会自己标EF),那么接入端口可以配置为信任DSCP;如果终端不可控,就要在接入层按VLAN、IP或ACL做一次重标记,把该给语音的给语音、该给视频的给视频,再向上传递。信任还是不信任,本质上是个管理策略选择,没有绝对对错,但必须明确配置,否则设备默认行为很容易让QOS策略失效。
4. 实操过程与关键配置实现
4.1 一个典型场景:办公网语音视频优先
假设一个中等规模办公园区网,接入交换机上接了三种终端:IP话机在VLAN 10,视频会议终端在VLAN 20,普通办公电脑在VLAN 30。需求是语音必须最优先,视频其次,普通办公流量尽力而为。方案在接入交换机上把所有语音流量统一标记为DSCP EF并信任处理,视频标记为AF41,普通数据保持BE。这样汇聚层和核心层只需根据DSCP做队列和带宽保障,全网策略一致。
4.2 华为VRP平台配置思路
以华为S系列交换机为例,我一般用流策略(traffic policy)来做入方向分类和标记。下面是一个有代表性的配置片段:
# 定义ACL,按网段匹配语音终端 acl number 3101 rule 5 permit ip source 192.168.10.0 0.0.0.255 # 定义流分类 traffic classifier voice if-match acl 3101 traffic classifier video if-match acl 3102 # 定义流行为:重新标记DSCP traffic behavior voice remark dscp ef traffic behavior video remark dscp af41 # 定义流策略并绑定关系 traffic policy access_mark classifier voice behavior voice classifier video behavior video # 在接入接口入方向应用 interface GigabitEthernet0/0/1 traffic-policy access_mark inbound如果你用的是支持直接信任DSCP的型号,配置更简单,只需在接口下加trust dscp,但前提是终端已经打好了标记。实际项目中,我会优先在接入层做重标记,因为这样不管终端怎么配置,最终进入网络的优先级都是可控的。
还需要注意:华为设备流行为里也支持remark local-precedence设置内部本地优先级,这个值是设备内部调度用的,不同型号有差异。建议只做DSCP重标记,后续队列映射交给汇聚层统一处理,避免把配置写得太死,后期难维护。
4.3 Cisco IOS XE等价做法
Cisco体系里用的是MQC模块化QOS CLI,逻辑和华为很像,同样是class-map + policy-map + service-policy三段式。下面是等价配置:
class-map match-any VOICE match access-group name VOICE_ACL class-map match-any VIDEO match access-group name VIDEO_ACL policy-map ACCESS_MARK class VOICE set dscp ef class VIDEO set dscp af41 class class-default set dscp 0 interface GigabitEthernet0/1 service-policy input ACCESS_MARK注意这里 class-default 我把DSCP设置为0,是为了明确告诉设备“普通流量按默认处理”,防止原来报文里带了其他值造成意外。这个习惯后来帮我在多次测试里减少了很多莫名其妙的干扰。Cisco里match dscp也可以直接在 class-map 内匹配,比如match dscp ef,适合已经信任DSCP的场景。
4.4 验证:让配置真的被看到
配置完不是结束,必须验证。华为设备上推荐看流策略统计,检查匹配报文数是否在增长:
display traffic classifier statistics interface GigabitEthernet0/0/1 inbound这条命令能看到每个分类器匹配到的报文数、字节数,如果匹配数为0,说明流量没进到预期分类,需要检查ACL和策略绑定是否正确。Cisco设备则用:
show policy-map interface GigabitEthernet0/1能看到每个类的packets统计和动作执行情况。要确认DSCP真的被改写成预期值,最直接的办法是抓包验证。在接口镜像或PC上抓包后,用Wireshark看IP头里的Differentiated Services Field:语音包显示DSCP: EF (46),视频包显示DSCP: AF41 (34),说明标记生效。这里有个细节:很多抓包工具默认显示ToS/DSCP时带有ECN位,要区分清楚DSCP数值才是真正的标记值。
5. 常见问题与排查技巧实录
5.1 流量没有进入预期队列
最常见的问题是配置了分类策略但流量始终匹配不上。我的排查顺序是:先确认流量实际走到哪个接口,再看策略应用方向是否对——分类标记通常做在入方向。有些朋友把策略挂在出方向,结果看到的是队列调度生效,分类统计一直为0,其实是方向理解错了。
其次检查匹配条件。ACL配的是源网段是192.168.10.0,但如果终端实际走的是另一个网段,自然匹配不上。还有一种隐蔽情况:设备上有多个策略叠加,比如端口下的VLAN策略、全局策略,匹配顺序或优先级不同,可能导致你的策略根本没生效。我会先用display traffic policy applied-record之类的命令看策略实际应用情况,确认没有冲突后再判断是否是匹配条件本身的问题。
5.2 DSCP被改了但下游设备不认
标记配置正确,本机上查看DSCP也变了,但下游设备依然按普通流量处理。这种问题十有八九出在“下游接口不信任DSCP”上。QOS策略是否生效,取决于路径上每一跳是否配合。第一跳改了DSCP,第二跳设备默认不信任,照样按0处理,那标记就白做了。
解决思路是端到端做一次QOS域规划:接入、汇聚、核心全部统一配置信任DSCP,或在每跳做相同的重标记。我习惯在网络设计阶段就把“标记在哪几个设备上做、信任从哪台设备开始”写清楚,避免上线后一台台排查。你可以在每一跳设备上分别用统计和抓包确认DSCP传递情况,定位是哪一段“丢标签”。
5.3 隧道/MPLS场景标记失效
隧道场景在前面提到过,实际排查中特容易让人懵。比如报文在接入设备上标记了DSCP EF,但流量走VXLAN后,中间设备只认出外层VXLAN头封装,原有的DSCP就看不到了。更麻烦的是有些封装默认不会把内层优先级复制到外层,导致中间网络完全“无视”你的标记。
处理办法一般有两个:一个是在隧道封装设备或出接口上加标记动作,让外层IP头继承或重写DSCP;另一个是采用支持DSCP/QOS映射的隧道协议配置参数,很多平台上有类似qos map的选项可以配置内外层字段映射。最实用的建议是抓包看两个位置的报文头——隧道入点之前和出点之后,对比外层DSCP,问题立刻清晰。
5.4 分类性能与硬件表项
简单分类之所以叫“简单”,正是因为对设备硬件友好。但有一些所谓“简单配置”其实消耗不小,例如把ACL规则写得特别多、特别碎,或者每条流分类都单独建一条匹配规则,累积起来可能占满设备硬件表项。中低端交换机上,复杂ACL规则数量是有限制的,规则过多会直接导致后续规则匹配不上或转发性能下降。
我的习惯是尽量合并规则,能用网段的不用单IP,能用DSCP区间不用逐条枚举,能按VLAN区分的就不写IP。对于需要精细分类的流量,只针对核心关键业务做规则匹配,其他流量全部归到类默认。这样既保证QOS效果,又保住设备转发性能和表项余量。每次配置完我都会在终端设备上刷新一下数据面统计,观察CPU和表项占用,确保没有引入隐性负载。
做QOS的这几个月里,我感触最深的一点是:分类标记看起来只是“给报文贴个标签”,但真正的难点在于让全网的设备按同一套规则认标签、传标签。先把简单分类和标记这一步做扎实,后面的队列、带宽、丢包策略才有意义。最后再分享一个实操小习惯:每台设备的QOS配置模板我都会注释清楚用途、DSCP取值和对应业务,并建议团队统一用同一个模板变体。这样每次排查问题时,不用从头猜配置意图,直接对照模板就能定位是哪一跳出了问题。