X

网工的噩梦:关于服务质量(QoS)的一二事—网络很难学

弈心:从事计算机网络工作十年(新加坡7年,沙特3年),2013年考取CCIE,在新加坡先后任职于AT&T,新加坡交通部,苹果,Equinix,苏格兰皇家银行等大型企业、银行和政府部门。 目前供职于“世界第一土豪大学“沙特阿卜杜拉国王科技大学(KAUST),担任Senior Network Engineer,为KAUST校史上第一位也是唯一一位华人IT部门高级职员。2019年6月在知乎发布了华语圈第一本专门为编程零基础的网络工程师量身打造的Python教程《网络工程师的Python之路》。

今天聊下不少网工学了就忘,忘了又学,干了一辈子网络几乎都没一个完整的概念,甚至在工作中都没太多机会接触的一个技术话题:服务质量 (Quality of Serivce)。开篇前先讲讲为什么我要在标题里加入一个“网络很难学”的副标。

很多人在知乎上或私信或付费咨询向我询问如何学习计算机网络,如何在短时间内迅速在这行里积累拿到高薪。这些朋友当中既有为高考后选择大学专业感到困惑的大学新生,也有工作了若干年对目前自己所在行业不甚满意想要改行跳槽的职场人士。而我无一例外对他们的建议是:网络知识很抽象、很枯燥、很难学,要想在这行走得远,爬的高,你必须耐得住寂寞。

学网络不像学编程,我可以10秒钟教会你如何用python 3来print (“Hello World!”),5分钟教会你什么是列表,10分钟教会你如何写一个最简单的for循环来遍历列表里的元素。但我没办法在同样那么短的时间内向你解释清楚什么是IP地址,什么是子网掩码(以及反掩码),什么是默认网关,更不用说跟你解释清楚它们之间的关系(如果你没有学过二进制就更难跟你讲明白了),你就算把这类网络最基础的东西学会后也没有像用编程语言打印出”Hello World”那种所见即所得的成就感可言,因为你身边没有一个现成的网络给你练习和试手;别人学编程一台笔记本就够了,你学网络考证还得租机架在真机上练习。就算有模拟器这个东西,真实的网络和模拟器也是天差地远,还得重头向你解释怎么使用模拟器,怎么搭建环境,在哪里下模拟器里要用到的IOS镜像文件;别人编程2,3个月能够开发一个网站,写个小程序,你学两三个月还在啃CCNA的书,还在背题库准备迎接考试。。。总之一言以蔽之:网络很难学,真的很难学,这个行业没有捷径可走,没有短期拿高薪的可能,如果你耐不住及寂寞,那么请谨慎入坑。

说完副标来说正题:

笔者从业10年来面试过不少人,发现很多网工对各种常用的VLAN,STP, NAT, 各种动态路由协议,网络抓包排错,甚至MPLS等等技术都掌握的很不错,但是一向他们问到QoS,这个相对前面提到的那些二、三层来说并不是那么常用的技术的相关问题时,他们的表现就不那么理想了。虽然不少人能正确回答EF的DSCP值是什么,能说出思科的MLS和MQC的区别及分别对应什么型号的交换机,知道语音网络对延迟,抖动,丢包能承受的范围是多少,能给我讲明白AF11和AF13在网络阻塞时哪个更有可能被丢弃,也能画图给我解释清楚流量整形(shaping)和流量整治(policng)的区别,因为这些都是书本上能找到答案,能够背下来的知识点。

但是当我拿出实际工作中遇到的和QoS相关的问题,并向他们询问排错思路、解法以及相应的原理是什么时,很少有人能完美的讲个清楚,所以今天这篇文章就来聊聊两个网络中常见的和QoS相关的问题及其解法。首先来看问题一:

问题一

背景:

网工A最近刚刚入职一家新公司,该公司的网络配置采用的是End-to-end QoS(端到端的QoS)的设计, 所有接入层交换机(思科3750)和汇聚层交换机(思科4509)都开启了QoS,接入层交换机下接网络电话的端口以及汇聚层交换机连接接入层的交换机的端口都配置了mls qos trust dscp,划分好了信任边界。 刚入职的网工A为了尽快了解现有网络的规划和部署,便将每台交换机的配置拿出来学习研究,他发现所有交换机中唯独有一台接入层交换机没有开启QoS:

access-sw#sh mls qosQoS is disabled

于是便自作主张在该交换机上开启了QoS,但是随即网工A就收到了其他组同事开来的ticket,他们有一台服务器直连在该交换机下,在该服务器上跑的程序一直因为高延迟的问题而报错。

问题:

网工A并没有改变该交换机下任何端口的配置,仅仅只是在这台3750上开启了QoS,请问为什么会导致终端用户应用延迟的问题发生?讲下原理和解法。

问题二

背景:

某土豪大学为所有师生和职员提供别墅作为住房,每栋别墅都配置了一台思科2960交换机,该2960交换机的级联端口(光纤)和用户端的端口(RJ45)均为100兆的Fastethernet,最近学校升级住家网络,将级联端口的SFP transceiver从100兆的GLC-FE-100BX-U换成了1G的GLC-BX-U,所有住家用户的2960交换机均开启了QoS(mls qos),级联端口的配置如下(网速升级后没有对交换机的配置做任何更改):

interface GigabitEthernet0/2 switchport trunk allowed vlan 2232-2235,3208,3999 switchport mode trunk switchport nonegotiate load-interval 30 media-type sfp srr-queue bandwidth share 1 40 30 30 priority-queue out mls qos trust dscp spanning-tree bpdufilter enable ip dhcp snooping trust

问题:

将级联端口从100M升级到1G后,不久就收到用户的投诉,说他们家里的网速明显变慢了很多,你在排错时做了speedtest,将级联端口为100M时的测速结果和1G时的测速结果做了对比,结果如下:

级联端口为100M时,下行速度达到了93.9Mbps。

级联端口为1G时,下行速度只有8.31Mbps。

请问为什么?不用给出具体配置方案,讲讲排错思路,以及涉及到的知识点即可。

答案:

这两道题都是笔者在工作中亲自碰到过的实战问题,具有极强的实用性,计算机网络那么多知识点里面就数QoS最抽象,最难学,很多网工能背下书本上的各种理论,但是一旦碰到和QoS相关的实战问题就会显得手足无措,不知从何下手。也有小部分网工能解决问题,但是无法系统的说出该问题涉及到了QoS的哪个知识点及其原理。笔者当年也是查阅了很多资料才做到了“知其然还要知其所以然“,希望下面的解答能给大家一点启发。

问题一解答

在回答”为什么网工A开启QoS后,用户端程序出现了延迟问题”之前,先来看下”为什么QoS在没有被开启的时候一切正常”。答案其实很简单:在QoS被关闭的时候,交换机对其吞吐的流量不做任何事情,从QOS的角度来讲,这时没有信任(Trust)和不信任(Untrust)之分,交换机不管这些流量自带的是什么DSCP, COS还是IPP值,统统放行。换句话说,这时给该程序流量做QoS标记(marking)的恰恰就是程序本身,并且该标记没有受到任何行为约束,自然该流量一切正常,没有延迟发生。

当网工A开启了QOS之后,交换机马上做了两件重要的事情:

  1. 所有端口默认为不信任任何DSCP值,也就是说该交换机所有端口的配置里现在多了一条”no mls qos trust dscp”。

2. 所有不信任DSCP值的端口会对流经该端口下的程序流量进行DSCP重写(ip packet dscp rewrite),默认状态下,所有程序自带的DSCP值将被交换机重设为0

这点可以在3750上show mls qos验证(看到QoS ip packet dscp rewrite is enabled了吗?):

access-sw(config)#mls qos
access-sw(config)#end
access-sw#sh mls qos
QoS is enabled
QoS ip packet dscp rewrite is enabled

那么DSCP被重设为0意味着什么?意味着现在该程序的流量在该网络下被分类为了BE(Best Effort,尽力而为)流量,BE流量出现高延迟的情况并不罕见。

解法:

找到问题的原因后就可以对症下药了,这道题大致有如下几种解法:

  1. 在连接服务器的端口下开启mls qos trust dscp,这个是最简单也是最直接的办法。

mls qos trust dscp

2. 还有一种很多人不太了解的解法,就是在交换机上开启DSCP透明模式(DSCP transparency mode), 让交换机不要重设不信任端口下收到的流量的DSCP值,(言下之意就是关闭默认开启的DSCP重写功能),开启DSCP透明模式的命令如下:

no mls qos rewrite ip dscp

3. 创建一个ACL来匹配该程序流量,然后手动将它标记为它原有的dscp值(复杂,不推荐)。

问题二解答

给出这道题的解法和原理之前,我们可以把级联端口和用户端口看成两根水管,先来看下级联端口提速前后的变化:

  1. 提速前:用户端口和级联端口均为100Mbps, 下行流量从级联端口到达用户端口时不会发生拥塞现象,因为两根一样粗的水管的容量是一样的。
  2. 提速后:级联端口变成了1G,管子增大了10倍,而用户端口依然是100M,你现在将大水管里的水往只有它容量10分之1的小水管里灌水,显而易见会发生拥塞现象。

既然涉及到了网络拥塞的现象,那自然而然就涉及到了QoS的队列(queueing)以及缓冲(buffering)的问题。队列的知识点又分为入队列(Ingress Queue)和出队列(Egress Queue)。这道题出现问题的是下行速度,所以我们要关心的是用户端口的出队列。

下面简要回顾一下出队列的相关知识点,注意加粗斜线部分为涉及到本题的重点内容, 其他部分了解即可。

  • 在思科的IOS交换机里面(以这里的2960为例),每个交换机端口有4个出队列。每个队列默认分配的缓存空间(buffer size)相等,都为缓存总量的25%(思科2960的硬件缓存总量为2MByte),缓存的作用是在交换机出队列出现拥塞的时候,额外分配硬件资源给出队列,换句话说就是分配更多的带宽给出队列,也就是把这道题里我们所比喻的客户端管子加粗。每个队列保留自己所得缓存空间的50%作为保留阈值(threshold)其中队列1使用shaped模式,其他3个队列使用shared模式,换句话说队列1只能使用总缓存空间的25%,超出这个空间的数据将被丢弃,而其他3个队列则是共享剩下的75%缓存空间,也就是它们理论上可以“独享”75%的缓存空间。
  • 要了解出队列还必须了解Queue-set。Queue-set本身是一个列表, 用来设定每个出站队列的buffer资源如何分配和使用。用户可以自定义的queue-set有两个:queue-set 1 和 queue-set 2。每个交换机的端口一次只能使用一个queue-set, 默认情况下,所有交换机的端口都在queue-set 1下。

我们可以使用show mls qos queue-set命令来查看Queue-set 1 和 2的参数,你可以看到默认状态下4个队列分别分配到了25%的buffers.

2960#show mls qos queue-set Queueset: 1Queue : 1 2 3 4———————————————-buffers : 25 25 25 25threshold1: 100 200 100 100threshold2: 100 200 100 100reserved : 50 50 50 50maximum : 400 400 400 400 Queueset: 2Queue : 1 2 3 4———————————————-buffers : 25 25 25 25threshold1: 100 200 100 100threshold2: 100 200 100 100reserved : 50 50 50 50maximum : 400 400 400 400

  • 每个出站队列的buffer有3个阈值(threshold):threshold 1, threshold2, threshold3。其中threshold 1和threshold 2可以自定义,threshold 3为固定值(100%),不可修改。 上面的命令Show mls qos queue-set的时候只能看到threshold 1和2,看不到threshold 3。阈值的意思是,如果一个队列使用的buffer达到了由阈值定义的百分比,则交换机开始丢包。比如说使用threshold 3(100%),那么交换机会在buffer的使用率达到100%后开始丢包。阈值1和阈值2最大可以修改到3200。

说了那么多,也许你有点眉目了,就是因为在拥塞情况下,交换机默认给每个出队列25%的buffer不够用,以致丢包,最终造成下行速度在级联端口升速后骤降。

如果你有经验的话,你可以show interface x/x | i output drops以及show mls qos interface x/x stat | b dropped这两条命令来查看output方向的丢包情况,通常这种级联端口和用户端口带宽不对称的情况都会造成output drop严重的问题(在跑完测速后,测速机器所连的用户端口fa0/2的Total ouput drops 达到了9346180,这个数字和队列2阈值1的丢包数据相同!

2960#show int fa0/2 | i output drops Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 93461802960#sh mls qos int f0/2 stat | b dropped output queues dropped: queue: threshold1 threshold2 threshold3———————————————– queue 0: 0 0 0 queue 1: 9346180 0 0 queue 2: 0 0 0 queue 3: 0 0 0

** 注意这里的queue 0对应的是出队列1, queue 1对应的是出队列2, 以此类推。

解法:

要解决这个问题,还要了解DSCP值和4个出队列的映射关系。

我们可以通过show mls qos maps dscp-output-q这个命令来查看DSCP值与出队列即阈值的映射关系:

2960#show mls qos maps dscp-output-q Dscp-outputq-threshold map: d1 :d2 0 1 2 3 4 5 6 7 8 9 ———————————————————— 0 : 02-01 02-01 02-01 02-01 02-01 02-01 02-01 02-01 02-01 02-01 1 : 02-01 02-01 02-01 02-01 02-01 02-01 03-01 03-01 02-01 03-01 2 : 03-01 03-01 03-01 03-01 03-01 03-01 03-01 03-01 03-01 03-01 3 : 03-01 03-01 04-01 04-01 04-01 04-01 04-01 04-01 04-01 04-01 4 : 01-01 01-01 01-01 01-01 01-01 01-01 01-01 01-01 01-01 04-01 5 : 04-01 04-01 04-01 04-01 04-01 04-01 01-01 04-01 04-01 04-01 6 : 04-01 04-01 04-01 04-01

  • 这个表的d1表示DSCP值的十位数,d2表示个位数。
  • 02-01表示出队列2,阈值1。 04-01表示出队列4,阈值1, 依次类推。

回到这道题来看,我们做测速的时候是在某测速网站做的,互联网流量的DSCP值为0,也就是BE尽力而为。通过上面的映射表可以看出,DSCP 00对应的是02-01,也就是出队列2,阈值1。

知道了流量对应的出队列和阈值后,我们就可以手动修改交换机对每个出队列的缓冲空间的分配了,既然默认的25%不够,那么我们可以多分点,比如分60%给出队列2,再把阈值1调高到3200。两条命令分别如下:

2960(config)# mls qos queue-set output 1 buffers 10 60 15 152960(config)# mls qos queue-set output 1 threshold 2 3200 3200 50 3200

首先讲下这条命令mls qos queue-set output 1 buffers 10 60 15 15, 这里的1表示queue-set 1,前面提到了IOS交换机有两个queue set,默认使用的是Qset 1,所以这里我们就直接改Qset 1的配置。 后面的10,60,15,15的意思也许你也猜到了,就是分别给出队列1分配10%的buffer, 给出队列2分配60%的buffer, 给出队列3分配15%的buffer, 给出队列4分配15%的buffer。

第二条命令mls qos queue-set output 1 threshold 2 3200 3200 50 3200, 这里output后面的1表示的依然是Qset 1, threshold后面的2表示的是出队列2,第一个和第二个3200分别表示阈值1和阈值2,50表示默认的保留阈值(前面有提到),最后的3200表示最大阈值。

配置好这两条命令后,问题完美解决。关于思科IOS交换机的完整出队列机制可以用下图概括起来。

结语:

如果从难度来评价这两道题的话,第一道题姑且算中级,第二道题则是真正的专家级难度,我在技术面试环节问到QOS时通常会用这两道题来考应聘者。

就如我在上篇文章里提到的一样:

当我在面试的时候向应聘者问到QoS相关的问题时,虽然不少人能正确回答EF的DSCP值是什么,能说出思科的MLS和MQC的区别及分别对应什么型号的交换机,知道语音网络对延迟,抖动,丢包能承受的范围是多少,能给我讲明白AF11和AF13在网络阻塞时哪个更有可能被丢弃,也能画图给我解释清楚流量整形(shaping)和流量整治(policng)的区别,因为这些都是书本上能找到答案,能够背下来的知识点。
但是当我拿出实际工作中遇到的和QoS相关的问题,并向他们询问排错思路、解法以及相应的原理是什么时,很少有人能完美的讲清楚。

QoS很难,真的很难,要想在这行混得好,成为真正的技术大神,那就绝对不能抱有“不求甚解”的态度。