网络时不时卡顿、视频会议断断续续、后台同步任务把带宽占满,这种场景在现网里太常见了。QoS(服务质量,Quality of Service)就是专门用来处理这类问题的机制集合:在有限的带宽条件下,按业务的重要程度重新分配网络资源,让该快的数据快起来,该让路的让路。这篇文章面向的是网络运维、IT工程师、刚入行做网络规划的同学,以及所有被带宽分配问题困扰的人,我会从原理讲到落地配置,把QoS的核心机制、服务模型、配置思路和排查经验一次性说清楚。
1. QoS到底是什么,它解决的是哪一类问题
1.1 网络拥塞才是QoS存在的根本前提
先说一个很多人容易忽略的事实:如果网络带宽永远够用,QoS就没有存在的意义。QoS所有机制的设计,都是为了应对同一种场景——拥塞。
拥塞的本质是“千军万马过独木桥”:某段时间内,进入网络设备的数据总量超过了设备转发能力和链路带宽的承载上限,数据就会在设备缓冲区里排队。排队排得久了,时延就能明显感觉到;缓冲区排满了,后续的数据直接就被丢掉了。丢包再触发TCP重传,重传的数据又挤进队列,进一步加剧拥塞,这就是网络上最常见的“拥塞崩溃”连锁反应。
需要特别强调一点:QoS不会增加任何链路带宽,它解决的从来不是“带宽不够”的问题,而是“带宽如何分配”的问题。拿一个生活场景打比方,一条单车道公路,早晚高峰所有车都堵在路上。QoS做的事情不是把路修宽,而是给救护车、公交车划出专用道,让它们在拥堵的时候也能优先通行。带宽这个资源本身没有增加,但关键的流量拿到了更确定的通行保障。
1.2 网络“不公平”的根源:TCP的贪心效应与业务之间的冲突
没有QoS干预的默认网络中,所有IP报文在网络设备里基本是同等对待的,一个先进来一个先转发,后进来就排队,排队放不下就随机丢弃。这种机制看似公平,实际上埋了一个很大的隐患:TCP流的霸占效应。
TCP协议天生是“贪婪的”。只要不发丢包,它就不断增大发送窗口,一直到把链路余量吃光才停。网络中只要有一两个大流量业务在跑(比如数据同步、备份任务、P2P下载),它们就会一起挤占掉绝大部分带宽。而语音、视频会议这类实时业务,恰恰有一个致命特点:既不能丢包又不能等。音频一个包晚到几十毫秒,听感上就是明显的卡顿和断续;视频画面稍微排队,马赛克、花屏就出来了。这些业务还往往没能力去“争抢”带宽,它们用的是UDP,不具备TCP那种拥塞退避的自我调节能力,于是只能被动地被TCP大流挤到墙角。
这就是QoS需要被部署的核心原因:人为干预流量调度,让网络从“大锅饭”变成“按需分配”。语音流量在拥塞时优先转发,关键业务流量得到带宽保障,背景下载流量被限制在允许的范围里,不允许它影响核心业务。QoS不改变TCP的竞争本性,只是改变了网络设备对报文的处理策略。
2. QoS的核心机制,一个一个拆开看
要理解QoS怎么工作,不能只看概念,要看它在设备里实际做了哪几件事。一套完整的QoS处理流程,通常包含分类与标记、队列与调度、丢弃策略与流量整形这几段,每一段解决的问题都不一样。
2.1 分类与标记:让设备先认出你的业务
QoS的交互逻辑其实很朴素:你想让设备区别对待某类流量,第一步一定是让设备识别出这类流量。这个过程叫分类,分类结果的落地形式叫标记。
分类的手段要看场景。最传统的方式是基于五元组的ACL匹配:源IP、目的IP、协议号、源端口、目的端口。比如识别出RTP的UDP端口段,就是语音流;识别出某台服务器IP加目的端口8080,就是财务系统流量。这种方式直观,但有一个问题:ACL条目一旦多了,匹配性能会明显下降,而且跨设备传递时无法延续。
更可扩展的做法是进入报文头里打标。二层有802.1p字段(也叫CoS,服务类别,3比特,取值0到7),三层有IP优先级(IP Precedence,3比特)和DSCP(差分服务代码点,6比特)。DSCP是目前用得最广泛的标记字段,因为它有64个取值,语义更丰富,还可以映射成不同行为集合。三层的DSCP标记跟着IP包走完整条网络路径,这就是“带标记转发”的基础。
这里有个实操中极易踩的坑:信任边界。交换机接入口默认会重写报文优先级,还是信任报文自带优先级?如果全网都信任报文自带的DSCP,任何一个终端用户都可以把自己的报文标记成最高优先级,等于绕过了QoS策略,甚至可能挤压掉真正的高优业务。稳妥的做法是:在接入层边缘设备上统一重新标记(重打DSCP),核心和汇聚设备只信任边缘传来的标记。
2.2 队列与调度:决定拥塞时谁先走
报文分好类、打上标之后,进入转发流程,如果遇到拥塞,设备会把这些报文放进不同的队列,再用调度器决定接下来优先转发哪个队列里的数据。这个过程是QoS的核心体现,也是配置时最容易出现理解偏差的部分。
主流设备上常见的几种调度机制各有分工:
- PQ(严格优先级队列,Priority Queue):高优先级队列里有报文就先发它,发完再发低优先级队列。优点是绝对保障高优流量,缺点是高优流量过大时,低优先级队列可能完全被饿死。
- CBWFQ(基于类的加权公平队列):每类流量分到一条独立的队列,按配置的带宽权重分配出口带宽,各类流量都能拿到保证带宽,不会互相饿死。缺点是所有队列按权重共享带宽,重要业务拿到的只是比例更高,仍然是“公平竞争放大版”。
- LLQ(低延迟队列):可以看作PQ+CBWFQ的结合体,把语音这类对时延极度敏感的流量放进严格优先级队列,其余流量按类分队列做加权公平调度。这是现网上部署最广泛的组合方案,语音低时延有了保障,其他业务也不至于被饿死。
选型时一个常见争议是:要不要把实时业务放进严格优先级队列?我的建议是,必须做带宽限制。严格优先级队列如果允许占满全部接口带宽,语音流量本身要是发生异常风暴,一样会把其他流量全部挤掉。传统的做法是把语音放进LLQ,同时设置最大带宽上限,不让它无限制吃资源。这个细节在后面的配置部分还会展开。
2.3 丢弃策略与流量整形:超出带宽之后的处理方式
队列调度解决的是“谁先走”的问题,但拥塞一旦严重到队列装满,就必须有人被丢包。问题的核心是:丢谁?怎么丢?
最简单粗暴的是尾丢弃(Tail Drop):队列满了,新来的报文一律丢弃。尾丢弃有一个很大的副作用:当多条TCP流同时撞到满队列时,它们会在同一时刻收到丢包信号,一起进入TCP超时退避,链路又突然空下来,然后它们又同时重传增长,形成周期性的“大部同步”震荡,链路利用率忽高忽低,非常难看。
WRED(加权随机早期检测)是更成熟的丢弃策略,它不等到队列满了才丢,而是随着队列深度逐渐增加,按一定概率随机丢弃部分TCP报文。被随机挑中的TCP流先退避,流量整体错峰,避免全局同步震荡。这里顺便提一句,WRED随机丢弃的是TCP报文,UDP语音流不具备退避机制,所以WRED一般不作用于实时业务队列,高优先级实时流量靠的是队列调度保证。
流量整形(Shaping)和限速(Policing)也常被混在一起。简单区分:限速是超过速率的报文直接丢弃或重新标记,是“硬切”,会诱发TCP重传;整形是把超出的报文先暂存在缓冲区里,按令牌桶速率慢慢发出去,是“软排队”。对于需要平滑输出的场景,比如分支机构上联低带宽链路,整形比暴力限速体验好得多。
3. QoS三大服务模型:从IntServ走到DiffServ
在设计QoS方案的时候,首先要选“路线”:整个网络用什么方式提供服务质量保障。业界历史上形成了三种服务模型,理解了它们的来龙去脉,就能明白为什么现在大家一说QoS,默认指的都是DiffServ。
3.1 Best-Effort:没有QoS的默认状态
尽力而为(Best-Effort)模型就是网络默认的状态。所有报文一视同仁,设备按到达顺序尽力转发,不提供任何承诺,不区分优先级,丢包、时延全部看运气。好处是极致简单、部署成本低、网络利用率高,适合普通互联网访问、文件传输这类“无差别”业务。
但尽力而为模型扛不住“关键业务+高并发+拥塞”的组合。视频会议在高峰期出现卡顿、上级要求保障核心业务链路,这些场景下继续挂着尽力而为不动,基本等于把服务质量交给概率。
3.2 IntServ:端到端的赛道预留,方向对了但跑不动
集成服务模型(IntServ)追求的目标很理想:在数据发送之前,从源端到目的端的每一条链路都通过RSVP协议提前预留带宽,所有经过的设备都承诺预留资源,整条路径的服务质量就变成了可确定的。
理论上这确实是最严谨的端到端保障方案,但落地路径上有三个致命问题:一是RSVP的信令状态需要在沿途所有路由器上保留,网络规模一大,设备状态表压力非常大,对硬件资源的要求太高;二是为每个业务流预留带宽,路由器要维护的流状态数量会随业务量线性膨胀,骨干网场景根本撑不住;三是预留的带宽在业务不发送时白白浪费,无法被其他流量复用。所以IntServ被普遍认为在大型网络中不具备可扩展性,这个模型今天更多地停留在学术和某些特定场景里。
3.3 DiffServ:真正被全网大规模部署的模型
区分服务模型(DiffServ)放弃了对端到端绝对质量的承诺,改为逐跳行为保障。它的思路是:报文在边缘设备上做分类和标记(DSCP),核心设备不维护流状态,只根据报文的DSCP值查一张映射表,决定放进哪条队列走什么调度策略。核心设备无状态、高性能,全网实现简单,扩展性极强。
DiffServ里的核心概念是PHB(逐跳行为,Per-Hop Behavior),RFC定义了AF等级(Assured Forwarding)、EF等级(Expedited Forwarding)、CS等级(Class Selector)等行为集合。EF对应低时延、低丢弃的优先转发,通常给语音;AF又细分为4个类别、3个丢弃优先级,给不同级别的数据业务使用。
现在我们做QoS,绝大多数情况下就是DiffServ模型。配置流程也可以概括成三步:在边缘打标,在核心按DSCP分类,在出接口用队列调度策略来保证各类业务的出口行为。
4. 一套可落地的QoS配置思路
理论讲得再多,不如一套实际能跑的配置。这里我以一个典型的企业/园区网络场景为例,走一遍从需求分析到配置下发的完整过程。
4.1 第一步:明确业务优先级和带宽配额
动手配置之前,先和业务方一起梳理出所有重要业务,并按重要程度排序。设一个典型的场景:某园区网络,出口带宽是100Mbps,核心业务有:IP电话语音、视频会议系统、企业财务ERP系统、普通员工上网流量、后台数据备份任务。
我通常会按下面这张表来梳理配额:
| 业务类型 | DSCP标记 | 调度策略 | 所需带宽保证 |
|---|---|---|---|
| 语音 | EF(46) | LLQ严格优先队列 | 10Mbps,最大不超过20Mbps |
| 视频会议 | AF41(34) | CBWFQ队列,配置保证带宽 | 30Mbps |
| 关键数据(ERP) | AF31(26) | CBWFQ队列,较大权重 | 20Mbps |
| 普通上网 | AF11(10) | 默认队列,动态共享 | 余量共享 |
| 后台备份 | CS1(8) | 最低优先队列,限制带宽 | 最大不超过10Mbps |
这个规划的意图很明确:语音的时延对带宽的需求是高但峰值不大,走LLQ低延迟队列绝不排队,同时限制上限20Mbps防止异常时挤占其他流量;视频会议对抖动敏感,需要稳定带宽放第二优先;ERP这类交互式业务不能等,给保证带宽;普通上网共享剩余带宽;后台备份给个硬上限防止大批同步任务把出口吃干。
4.2 第二步:在边缘设备完成分类与标记
到达核心设备之前,流量需要已经在边缘被打上正确的DSCP值。这个过程通常就是在接入交换机或者出口网关的入方向做的。
在某个常见企业级设备平台上,配置逻辑大概是这样的:
# 定义一个类,匹配IP电话的流量特征(按端口或IP识别) class-map match-any VOICE match ip dscp ef match ip precedence 5 # 定义标记策略,给不同业务打DSCP标 policy-map MARKING class VOICE set dscp ef class VIDEO set dscp af41 class ERP set dscp af31 class BACKUP set dscp cs1 class class-default set dscp default # 在接口入方向应用 interface GigabitEthernet0/0/1 service-policy input MARKING这里有两种思路:如果终端或者IP电话本身能发出带正确DSCP的报文,边缘设备可以“信任并放行”;如果终端不可信,就按ACL匹配端口/IP从新做标记。我在现网上一般都会选择后者,做统一强制标记,避免终端用户私自改标。
4.3 第三步:出接口的队列调度策略
标记完成之后,真正决定服务质量的是出口的队列调度策略,在出方向配置核心策略映射。还是同一个设备平台,典型配置如下:
# 定义各类流量行为 class-map match-any VOICE match ip dscp ef class-map match-any VIDEO match ip dscp af41 class-map match-any ERP match ip dscp af31 class-map match-any BACKUP match ip dscp cs1 # 定义调度策略 policy-map QOS-OUT class VOICE priority 10000 # LLQ严格优先级,峰值上限10Mbps police 20000 # 超出的部分丢弃 class VIDEO bandwidth remaining percent 40 # 保证剩余带宽比例 random-detect dscp-based # 打开WRED,按DSCP区分丢弃概率 class ERP bandwidth remaining percent 20 random-detect dscp-based class BACKUP bandwidth remaining percent 5 class class-default fair-queue # 默认流量在剩余带宽中动态共享 # 应用到出口接口 interface GigabitEthernet0/0/0 service-policy output QOS-OUT注意到语音用的是priority命令,这就是LLQ实现:它保证语音报文一进到队列就被插到最前面发送,不给它排队的等待机会,同时police限制最高20Mbps,不允许语音流量无限制地占用全部带宽。视频和ERP用bandwidth remaining设置剩余带宽的分配比例,意思是拥塞时先用语音的固定10Mbps,剩余的90Mbps按40:20:5在视频、ERP和备份之间分配。视频和ERP打开WRED,让它们在发生拥塞时能更平滑地丢包,避免TCP全局同步。
一个很容易被忽视的点:QoS调度策略只对拥塞才有意义。如果出口带宽常年闲置,队列不满,所有流量直接转发,配置了和没配置看不出区别。只有在拥塞发生的时候,队列调度才会真正接管转发顺序。
4.4 第四步:验证策略是否生效
配置下发之后,不做验证等于白干。我最常用的验证手段是看几个关键计数:
- 在出接口执行统计查看命令,看VOICE类里的匹配报文数是否在增长,确认分类是否命中到流量。
- 查看队列的丢弃计数值。如果语音类的丢弃数始终是0,说明LLQ确实没有排队的丢包问题;如果数据类的丢弃计数在持续增加,说明拥塞发生时数据流量在被正常限制。
- 查看警察(police)的超出计数,确认语音流量峰值并未超过设定的20Mbps上限。
真正的验证要结合业务做端到端测试。比如压满链路后同时开一场视频会议,观察画面是否还卡顿;或者备份任务和ERP并发运行,实测ERP的响应时延是否有保障。计数不骗人,但业务体验才是最终标准。
5. 常见问题与排查经验实录
QoS部署初期,我踩过的坑不少,几乎每个问题到后来都能总结成一条经验。这里挑几个最有代表性的情况,连同排查思路一起整理成速查表,方便日后对照处理。
5.1 配置了QoS之后感觉完全没效果
这是最多人反馈的问题。第一个排查点:拥塞是否真实存在。如果链路空闲、队列根本不堆积,QoS就没有出手机会,这是正常现象。但更常见的坑在分类和方向:
- 应用方向搞反:调度策略忘了,或者加在了入接口而不是出接口。QoS队列调度只在出方向生效,入方向只能做分类标记和限速。
- 分类匹配不上:DSCP标记和class-map里match的条件不一致。比如edge设备打的是AF41,核心设备的class-map却匹配AF11,所有流量落进默认类里,策略自然不生效。
- 信任模式没打通:报文经过第一跳交换机时,如果交换机默认重写了DSCP值,你在接入侧辛苦打的标记到核心设备全变样了。需要用命令显式配置信任或重标记行为。
排查顺序建议是:先确认分类命中,再确认应用方向,再确认拥塞条件,最后看队列计数。分类不命中是一切问题的根源。
5.2 丢包计数很高,如何定位是哪个环节在丢
区分丢包发生的环节,要看接口的丢包计数所在的统计位置。正常情况下,QoS相关的丢包会体现在队列丢弃或者警察丢弃里,而物理丢包(CRC错误、FCS校验失败等)会出现在接口物理层的错误计数中。
如果看到数据类的random-detect丢弃在增长,说明链路确实拥塞、WRED在工作,这是设计意图内的正常丢包;如果看到语音类出现了丢弃计数,那就要警惕了,大概率是语音的police上限配得太低,或者语音流量本身异常放大把上限顶爆了。还有一种情况是接口总带宽估算错误,比如物理接口为100Mbps,但出口实际被运营商限速到了30Mbps,队列还没开始排队,流量已经在物理出口被无声丢掉了。这种“内部不丢、外部丢”的情况最隐蔽,排查时要重点关注设备出接口的错包和丢弃统计。
5.3 高优先级业务被“饿死”了,反而是低优先级流量一直能走
方向反掉的变种。曾经有人配了策略想保障数据库业务,结果数据库响应反而更慢,定位发现策略被误加到了入方向:数据库流量进设备的时候就被警察给限速了。入方向的服务策略一般只做标记和限速,真正做带宽保障的调度策略必须在出方向。
另一个原因是LLQ带宽过度预留。语音队列按priority命令分配了带宽,如果这个值加上其他队列的保证带宽超过了物理接口带宽,会导致部分队列实际拿到的带宽缩水。配置前要先算账,所有保证带宽之和不能超过接口带宽。语音、视频和关键应用的保证带宽加起来,建议控制在接口总带宽的75%以内,留出余量给控制和突发流量。
5.4 QoS故障速查表:对照定位快速判断
| 现象描述 | 最可能原因 | 优先排查动作 |
|---|---|---|
| QoS全局无效果 | 分类未命中或接口未拥塞 | 检查class-map匹配计数、接口利用率 |
| 所有队列都丢包 | 总保证带宽超过接口带宽 | 核对各队列配置带宽是否超分配 |
| 语音仍卡顿 | LLQ未生效或DSCP被改写 | 检查语音类是否命中、各跳是否信任DSCP |
| 高优流量反而慢 | 策略误应用在入方向 | 确认调度策略在出接口 |
| 低优流量完全被挤掉 | LLQ语音队列未做限速上限 | 检查语音police上限是否配置 |
这张表基本覆盖了我这几年做的QoS排障里,九成以上的问题场景。遇到QoS异常不用慌,按这个思路逐层查,大部分问题都能定位到配置细节上。
6. 几条来自现网的实操心得
说了这么多,最后分享几个我自己踩出来的经验,谈不上高深,但确实能少走弯路。
第一,QoS一定要“边缘打标、核心信任”。所有终端侧的标记都不可信,接入设备必须做强制重标记,核心设备不要花费CPU去逐包做深度识别,直接信任DSCP按集合转发。这套架构既保证策略可控,也保证核心转发性能不被打折。
第二,不要试图用QoS解决“物理带宽不足”。如果出口链路常年利用率超过80%,看谁的QoS策略都只是拆东墙补西墙,该扩容就扩容。QoS优化的是资源分配,不是凭空变出资源。
第三,QoS上线前一定要先定好度量标准。哪几条业务是必须保障的,保障到什么程度,拥塞时谁先让路,这些如果不和业务方对齐清楚,光靠网工自己在设备上配参数,配完验收的时候依然说不清楚效果。
第四,所有变更都要留回退方案。QoS策略上线后出现业务异常,第一反应不是调参,而是先把策略摘掉恢复到原有状态,再逐步分析问题。拿着生产环境当试验田,代价往往比想象中大。
这些经验来自一次又一次的现网实践。QoS的配置本身不复杂,复杂的始终是弄清楚业务到底要什么、网络能给出什么,以及两者之间如何做取舍。做网络的人,真正的工作就是在这两者之间找到一个平衡点。