前些日子有个项目割接,客户反馈视频会议在晚高峰老是花屏,语音断断续续。我过去一看,发现网络设备里其实配了QOS调度,但问题出在最前面一环:报文进到设备时根本没做分类和标记,交换机根本不认识哪些是会议流量,后面的队列调度做得再精细也使不上劲。后来我们把“分类+标记”补上,耗时不过两小时,问题立刻缓解。这个经历我一直记得:QOS里最基础的动作,往往才是决定成败的动作。
这个话题在我系列第一篇里聊过QOS的整体设计思路,这篇专门拆开讲“报文分类和标记”这一环。如果你也想搞清楚“为什么打了标就能优先转发”“DSCP和802.1p到底怎么选”“华为、思科、华三设备上怎么配”,这篇应该能给你一个比较完整的答案。内容不追求大而全,只围绕“简单分类”和“标记”这两个动作,把原理、配置、排错一次讲透。
1. 为什么“分类+标记”是整个QOS体系里最容易被低估的一步
1.1 流量识别的本质:把带宽资源翻译成业务优先级
很多人以为QOS就是做队列调度,就是在设备出接口上配置PQ、WRR、WRED这些高级功能。其实QOS是一个完整链条,大致可以分成四步:分类识别、打标、入队调度、拥塞管理。第一步就是识别出“这个报文是谁”,第二步是“给它贴个标签”,后面才能谈得上“按标签进不同队列”。如果前两步没做,后面的调度全是空中楼阁。
我打个比方。高铁站进站时,如果工作人员不知道谁是商务座乘客,也没法给任何人发VIP手环,那到了人流拥挤的时候,所有人都挤在同一个入口,商务座旅客再着急也进不去。分类就是“认出商务座旅客”,标记就是“发VIP手环”,队列调度就是“让手持VIP手环的人走专用通道”。QOS并不能凭空增加带宽,它只是在拥塞发生时决定“谁先走、谁多走、谁让路”,所以前提一定是设备能认出业务类型。
还要理解一个容易被忽略的点:分类和标记的影响范围不是单台设备的,而是端到端的。报文一旦在接入交换机上被标成了高优先级,这个标记就会跟着报文一路走到核心、出口甚至对端网络,所有中间设备都会“默认信任并放行”。反过来,如果在接入层标错了,一个原本普通的下载流量被标成EF,它会抢占整条链路的优质队列,影响的不只是它自己,而是后面所有排队等待转发的业务。这也是为什么我总说,分类标记出问题,影响的是整条路径上的全局体验。
1.2 简单分类和复杂分类的取舍:先看报文头,再谈内容识别
在正式配置之前,先要把“简单分类”和“复杂分类”的概念理清楚。标准术语里,简单分类通常指基于报文已有的二层、三层头部字段来识别,比如VLAN、MAC地址、源目的IP、协议号、端口号,甚至报文里已经带有的DSCP或802.1p优先级。这种方式的优点很直接:报文头是固定格式,设备可以靠硬件芯片高速匹配,几乎没有性能损耗,配置也一目了然,出问题了好排查。
复杂分类则是指基于应用层内容去识别,比如设备要读出HTTP的Host字段判断是不是视频流量,或者通过DPI特征库识别出微信视频、抖音、BT下载等具体应用。这种方式精度高,能识别出“同一个IP不同应用”的差异,但代价是性能开销大,很多盒式交换机靠CPU处理根本扛不住高吞吐,而且依赖特征库持续更新,新应用一出现识别就可能失效。
那到底选哪种?我个人的项目经验是:80%以上的分支机构和园区网场景,用简单分类就够了。语音、视频会议、办公系统、普通上网,都可以通过网段和端口来区分,QOS的目标是“大致保障优先级”,不是做应用级的精细计费,没必要为了识别一个抖音去上一套DPI设备。复杂分类更适合放在出口防火墙、上网行为管理这类专门设备上,由它们识别完应用后,再给报文重新打标,这样交换机仍然只需要做简单匹配。分类不是越复杂越好,而是越稳越好,“简单分类+核心调度”的组合,在实际网络里远比“什么都要识别”更可靠。
| 对比维度 | 简单分类 | 复杂分类 |
|---|---|---|
| 匹配依据 | VLAN、MAC、五元组、DSCP | 应用层特征、行为特征 |
| 性能开销 | 低,芯片级查表 | 高,依赖CPU/DPI引擎 |
| 配置复杂度 | 低,易排错 | 高,依赖规则维护 |
| 典型位置 | 接入交换机、汇聚交换机 | 出口防火墙、上网行为设备 |
| 优势 | 稳定、高速、可预期 | 识别粒度细、能区分应用 |
| 不足 | 只能按网络层特征粗分 | 性能压力大、特征库滞后 |
2. 报文标记打在哪个位置:DSCP、802.1p、IP Precedence选型与换算
2.1 三类常见标记字段的位置和属性
报文“标记”并不是往报文里塞一段自定义数据,而是把报文头部里预留的优先级字段改写成一个约定的值。最常见的三个字段是802.1p、IP Precedence和DSCP,三者的层次和作用域完全不同。
802.1p也叫CoS(Class of Service),它藏在二层VLAN Tag里的Priority字段,一共3 bit,取值范围0~7。它只在二层网络里有效,出了VLAN或者穿越三层路由就会被剥离,所以适合在局域网内部、交换机到交换机之间传递优先级。IP Precedence是IP头部ToS字段的高3 bit,取值也是0~7,是早期DiffServ体系里的老办法,现在单独用的已经很少,但它的名称还经常出现在老设备的命令和抓包里。
DSCP是当前最推荐也最通用的标记字段,它占据IP头部ToS字段的高6 bit,取值范围0~63。它把原来的IP Precedence从3 bit扩展到了6 bit,可以表达更丰富的服务等级。要注意的是,DSCP和IP Precedence共用同一个字节,只是切割位置不同:IP Precedence只看前3 bit,DSCP看前6 bit。在抓包里看到的ToS字段值是“整个字节的十进制值”,所以做配置和验证时,经常要在DSCP值和ToS字节值之间换算。
| 字段 | 所在位置 | 长度 | 取值范围 | 作用范围 | 常见场景 |
|---|---|---|---|---|---|
| 802.1p/CoS | 二层VLAN Tag | 3 bit | 0~7 | 二层网络 | 交换机之间优先级传递 |
| IP Precedence | IP头ToS字段高3 bit | 3 bit | 0~7 | 三层网络 | 老设备、兼容场景 |
| DSCP | IP头ToS字段高6 bit | 6 bit | 0~63 | 三层及端到端 | 现代网络QOS标准方案 |
| MPLS EXP | MPLS标签 | 3 bit | 0~7 | MPLS网络 | 运营商骨干网QOS |
2.2 常用DSCP取值与PHB语义:EF、AF、CS、BE怎么选
DSCP不只是“填一个数字”那么简单,它背后有一套PHB(Per-Hop Behavior,逐跳行为)标准,也就是约定“看到这个码点,每台设备应该用什么方式对待它”。理解了这套语义,才不会把DSCP值乱填。
最重要的两个PHB是EF和AF。EF(Expedited Forwarding)对应DSCP值46,语义是“低延迟、低抖动、低丢弃”,典型场景就是VoIP语音,所以业界普遍把语音流量打成EF。AF(Assured Forwarding)是一个家族,分为AF1x到AF4x四个大类,每类又有三个丢弃优先级,比如AF41对应DSCP 34,AF42对应36,AF43对应38。AF的语义是“保证一定带宽,但拥塞时可以按丢弃优先级逐步丢弃”,适合视频会议、重要业务数据这类“可以稍有延迟但不能丢太多”的流量。CS(Class Selector)兼容老的IP Precedence,取值对应8、16、24、32、40、48、56,其中CS6(48)通常预留给网络控制协议,比如路由协议报文。
实际选值时我一般遵循一套很简单的套路:语音用EF(46),视频会议用AF41(34),重要业务数据用AF21(18),普通上网不用标,保持默认的BE(0)就行。这样既符合RFC推荐,又方便跨厂商理解。还有一个实用技巧,配置完后抓包验证时,需要把DSCP值转换成ToS字节值来看,因为Wireshark里显示的是整个ToS字段。换算方法很简单:DSCP值左移两位就是ToS字节值。EF的DSCP是46,46×4=184,也就是0xB8,所以抓包看到ToS=184就知道报文已经被标成了EF。
| 用途 | DSCP值 | 对应ToS值 | PHB | 推荐设备 |
|---|---|---|---|---|
| 语音 | 46 | 184 (0xB8) | EF | IP电话、软终端 |
| 视频会议 | 34 | 136 (0x88) | AF41 | 视频终端、MCU |
| 重要业务数据 | 18 | 72 (0x48) | AF21 | ERP、OA服务器流量 |
| 网络控制 | 48 | 192 (0xC0) | CS6 | 路由协议、网管报文 |
| 默认尽力而为 | 0 | 0 (0x00) | BE | 普通上网、下载 |
2.3 信任还是重标记:接入层与骨干层各自该怎么处理
设备面对一个已经带了优先级字段的报文时,有两种处理方式:信任(trust)或者重标记(remark)。信任就是直接用报文里原有的DSCP或802.1p值参与调度;重标记就是不管报文原值是什么,统一按本地策略改写。
这个选择题决定了整张网络的QOS风格。我的建议是:接入层设备做重标记,汇聚、核心、出口设备做信任。原因在于,接入层离业务源最近,只有在这里才能把“用户是谁、业务是什么”和优先级建立关系。比如IP电话接在接入交换机上,接入交换机看到这个端口的流量,就知道应该打EF;如果接入层不做,等报文到了核心再想判断,核心根本不知道它来自哪个端口,判断逻辑会变得非常复杂。而在接入层打标之后,上游所有设备只需要信任这个标记,按相同的PHB语义处理即可。
还有一个常见误区:很多人以为在核心设备上配一个大的QOS策略就能覆盖全网络。实际上报文的优先级字段应该在整个传输路径上保持一致,如果在核心重新打标,那接入层辛辛苦苦做的分类就白费了,下游出口设备看到的又是一个“标准值”。所以最佳实践是“接入重标记、骨干全信任”,每台设备只做自己该做的动作,整个链路才有一致性。
3. 实操配置案例:把语音流量标成EF并让办公流量保持BE
3.1 拓扑场景与QOS设计思路
假设一个很常见的分支办公网络:接入交换机上GE0/0/1接IP电话,GE0/0/2接办公PC,GE0/0/3是上行口接到汇聚交换机,汇聚再往核心走。IP电话和PC分属不同的IP网段,语音是192.168.20.0/24,办公是192.168.10.0/24。我们的目标是:语音流量在接入交换机入方向打上DSCP EF,办公流量什么都不改,保持默认BE。之后汇聚和核心设备信任DSCP值,让EF流量进入高优先级队列。
有人会问,为什么不直接在两条入接口上按端口打标,还要用ACL匹配网段?因为IP电话和PC可能不在一个物理端口上,也可能同一个端口下接了IP电话和PC的聚合交换机,按网段匹配更稳定,配置一次就能覆盖所有终端。这个设计思路的另一个好处是,语音网段被ACL精确匹配,即使办公PC的网络被人为改到语音网段,也会被识别成语音优先级,有利于从网络层面约束终端接入。
配置前最好先画一张标注了“哪类流量、从哪进、打什么标、信任还是重标记”的表格,贴在维护文档里。这样做的好处是等设备数量多了以后,不会忘记每一跳当初的设计意图。下面我以华为S系列交换机为例,给出完整配置步骤,然后再补充思科、华三的差异点。
3.2 华为设备配置步骤与验证命令
华为交换机的QOS配置采用“流分类+流行为+流策略”三段式结构,也就是先把要匹配的流量挑出来,再定义一个对流量执行的动作,最后把两者绑定成策略并应用到接口。下面是核心配置。
# 第一步:定义ACL,匹配语音网段的流量 acl number 3000 rule 5 permit ip source 192.168.20.0 0.0.0.255 # 第二步:定义流分类,并把ACL挂进来 traffic classifier voice if-match acl 3000 # 第三步:定义流行为,动作为标记DSCP EF traffic behavior voice remark dscp ef # 第四步:创建流策略,把分类和行为绑定 traffic policy QOS classifier voice behavior voice # 第五步:在接入交换机下行接口入方向应用策略 interface GigabitEthernet0/0/1 traffic-policy QOS inbound这个过程中有几点值得解释。ACL里rule 5的编号是人为起的起始编号,多条规则按编号从小到大匹配,编号越小越先匹配;如果后面还有办公网段、视频网段的规则,建议编号留出间隔,比如5、10、15,方便以后插入新规则。traffic classifier默认条件下,多个if-match条件是“与”的关系,如果只想匹配其中一个条件就命中,需要加上match-any参数,这是华为配置里很常见的一个坑,尤其是策略里同时匹配多个ACL时,一定要搞清楚逻辑关系。
应用策略的时候,inbound和outbound方向要拎清。我们是在报文从终端进入交换机的瞬间打标,所以用的是inbound。如果错误地配成outbound,策略会匹配从交换机发往终端的流量,那语音终端的入方向优先级根本不会被改写。这也是很多新手第一次配置QOS最常犯的错。
配置完之后,光看不报错还不够,要用验证命令确认策略真的在工作:
# 查看全局已应用的策略记录 display traffic policy applied record # 查看指定接口策略命中统计 display traffic policy statistics interface gigabitethernet 0/0/1 inbound # 查看接口的信任模式和映射关系 display qos trust interface gigabitethernet 0/0/1重点关注statistics里的匹配计数,如果有语音流量经过,计数应该是持续增长的。如果计数一直为0,说明流量根本没被匹配上,大概率是ACL写法或策略应用方向的问题,这时候再回头检查配置,不要急着怀疑设备故障。
3.3 思科、华三配置对照与跨厂商互操作要点
思科的QOS配置也是MQC三段式,只是命令名字不同。类图(class-map)负责筛选流量,策略图(policy-map)负责定义动作和服务策略(service-policy)负责应用。语音打EF的典型配置如下:
# 定义ACL,匹配语音网段 ip access-list extended VOICE_ACL permit ip 192.168.20.0 0.0.0.255 any # 定义类图 class-map match-all VOICE match access-group name VOICE_ACL # 定义策略图,动作是标记DSCP EF policy-map QOS_POLICY class VOICE set dscp ef # 应用到接口入方向 interface GigabitEthernet0/1 service-policy input QOS_POLICY华三的配置风格和华为非常接近,也是traffic classifier、traffic behavior、qos policy三段,只是应用接口的命令略有不同,典型的写法是qos apply policy QOS inbound。华为、华三命令差异不大,但思科的关键字是set dscp,华为是remark dscp,同平台不同版本之间也有差异,配置时最好先打问号确认关键字。
跨厂商网络里最重要的是统一“DSCP语义”,不要让同样的EF值在华为和思科设备上映射到不同的出接口队列。虽然各厂商都有默认的DSCP到队列映射,但默认映射往往不完全一致,强烈建议在核心和汇聚设备上显式配置一套全网络统一的映射表,让EF进最高优先级队列、AF4x进次高队列、BE进默认队列。互操作时还要注意:802.1p优先级在跨VLAN或三层转发后会被剥离,而DSCP可以跨三层传递,所以跨厂商、跨三层环境优先选择用DSCP作为全链路标准。
4. 常见问题排查与避坑实录
4.1 报文没有被标记:检查清单与定位思路
QOS配置完成后,最常遇到的问题就是“策略明明配了,但抓包一看DSCP还是0”。遇到这种情况,我一般按下面的清单逐项排查,效率很高。
第一,检查策略下发的接口和方向。策略是应用在流量进入设备的那一侧,不是流量发出的那一侧,如果inbound、outbound搞反了,必然不生效。第二,检查ACL匹配条件。源目的IP、掩码、端口号是不是写反了?很多交换机ACL默认隐含拒绝一切未匹配流量,如果ACL里规则没写全,被策略引用的分类可能根本不命中。第三,查看匹配计数。display traffic policy statistics是最好用的开始,计数为零就直接说明规则没匹配上,省去大量猜测。第四,确认策略有没有真正应用成功。有的设备上先应用策略再删除被引用的ACL,会导致策略空洞化,接口状态显示normal但实际什么都没做。
另外提醒一句:有些交换机在trunk口或VLANIF接口上也能应用QOS策略,但物理接口和VLANIF同时应用不同策略时,可能会产生作用顺序的冲突。不要图省事全局乱套,要逐接口确认,必要时在维护文档里记录每个接口绑定的策略名。
4.2 标记字段与调度队列不一致导致的“假QOS”
这是我在实际项目里遇到最多、也最隐蔽的一类问题:报文已经被标记成了EF,入方向策略也生效了,但业务表现还是该卡还是卡,像是什么都没发生。原因在于,标记只是“写标签”,而让标签发挥效果的是“按标签入队调度”。很多设备在接口入方向做了remark,但出方向没有把DSCP映射到对应的队列,或者出接口的队列调度策略忘记配置了,那么即使报文头显示EF,它依然和BE流量挤在同一个队列里,优先级形同虚设。
处理办法是检查出接口的QOS队列配置,确认DSCP、802.1p与本地队列的映射关系。比如华为设备上可以配置diffserv domain,把EF映射到PQ队列,把AF4x映射到WFQ高权重队列。思科设备则在出接口的policy-map里定义class,再通过priority或bandwidth命令给EF流量保障。说到底,QOS是一条完整的“分类->标记->入队->调度”链路,只改前半段、不管后半段,效果必然打折。
还有一个跨厂商的隐藏坑:部分厂商的交换机在默认情况下,出方向的队列调度只认802.1p,不认DSCP。如果你的报文在三层被打成了DSCP EF,但二层VLAN Tag里的802.1p还是0,那么这台设备可能压根不认为它是高优先级。解决思路是明确“全链路以哪个字段为准”,要么把DSCP同时映射并写入802.1p,要么显式修改设备的调度判据,让它从802.1p改为DSCP。
4.3 用Wireshark验证标记与逐跳定位改写点
验证标记最终的证据就是抓包。抓包时建议在打标设备的出方向做镜像,不要在终端接入侧抓,因为报文还没被打标。打开Wireshark后,找到IP层,如果看到Differentiated Services Field显示DSCP: EF (46),那就说明打标成功。如果这一行还显示着DSCP: Default (0),那就要回到4.1的清单重新排查。
抓包验证时还有个小技巧:把抓到的192.168.20.0/24网段的语音报文过滤出来,然后对比办公网段流量的ToS字段,两者差异应该非常明显。语音的ToS是0xB8(184),办公是0x00,一眼就能分辨。如果中间还有MPLS网络,MPLS标签里的EXP字段也会参与优先级传递,但EXP和IP DSCP的映射是另一套配置,跨运营商线路时容易丢标记,需要和运营商提前确认清楚。
对于“报文在中间某一跳被改写”的定位问题,我试过最有效的方法是在每一跳设备的入和出方向分别镜像抓包,逐段对比ToS字段。哪一段之前还是EF、之后变成了0,问题就出在哪一跳。大多数情况下是因为中间设备配置了QOS重标记策略,或者接口trust模式不对,把原来的标记重置了。逐跳抓包看起来麻烦,但比背配置要可靠得多,尤其适合交接不清晰的存量网络。
最后的经验
QOS这个东西,我一直觉得是张“端到端的协作网络”,不是某一台设备能独立完成的事。分类和标记作为第一环,看起来简单,实际上牵扯到接入、汇聚、核心、出口每一跳,牵一发而动全身。配置容易,命令就那么几行,难的是想清楚“哪类流量该打什么标、每跳是信任还是重标记、队列映射怎么统一”。我个人的习惯是动手前先把设计意图用表格画出来,再上线操作,比边敲命令边想方案稳妥得多。
另外再说一个很实在的建议:QOS上线后不要急着走,留几天观察期,重点看语音和视频在晚高峰的表现,同时抽查抓包确认标记没有被中间设备洗掉。一次故障往往不是因为配置写错,而是因为“某一跳设备不认这个标记”。多验几次,把链路每一跳都摸透,这套QOS才能真正让人省心。