第 2 章 · 服务器第 3 页,共 4 页
同时来的人一多,为什么会越来越慢?
晚饭前打开百家菜的人最多,页面越来越慢,偶尔打不开。这一页把每秒请求数一点点调高,看服务器怎样从空闲变忙,排队怎样先缓后急,以及等得太久的请求怎样失败。
为什么需要
百家菜是本课程虚构的家常菜谱网站,每天 17:30 到 18:30 来看菜谱的人最多。读者打开菜谱时,手机向(一直开着、等别人来要东西的电脑)发出(说明想要什么的消息)。访问有多繁忙,常用(requests per second)来衡量,即一秒钟里到达多少个请求。大型服务的这个数可以非常大:亚马逊存放文件的服务 S3,每秒处理超过 2 亿个请求。
服务器一刻不停地处理时,平均每秒能处理完多少个请求,叫它的(capacity)。你平时说的「容量」多指能装多少,比如硬盘有多大;这里指一段时间里能做完多少。这一页里,百家菜服务器的容量是每秒 50 个。那么晚饭前每秒来 45 个,没超过 50,是不是就不会慢?直觉会说:人数翻一倍,等待最多也翻一倍。下面的模拟会说明,并不是这样。
怎样做
请求到达的时刻是随机的:有时一下子来好几个,有时好一会儿一个也没有;处理每个请求的时间也有长有短。服务器正忙时,后来的请求只好等前面的处理完,这叫(queueing)。一个请求在服务器上的用时,等于排队的时间加上处理的时间。
为了看清排队,下图把服务器简化成一次只处理一个请求,处理一个平均要 20 (千分之一秒),所以容量是每秒 50 个。真实服务器的有好几个核心,能同时处理几个请求;越接近容量,等待涨得越急,这一点不变。一个请求排队 2 秒还没轮到,读者就收不到菜谱页,这个请求算失败。在下图里调节每秒请求数,看队伍、读数和曲线图怎样变化。
排队:每秒请求数越接近 50,等待涨得越急
先看这里先选「每秒 25 个」,直接看第 30 秒,曲线图上会描一个点;再依次换成 40、45、48、55,看点怎样越升越快。
排队的示意图:左边是正在到达的请求,中间是排队的请求,右边是百家菜服务器,框底部的负载条表示负载。
- 完成:请求处理完,响应发回读者
- 失败:读者没有等到响应
还没开始。选好每秒请求数,按「下一步」或「自动播放」,也可以直接看第 30 秒。
更多读数:实际到达、吞吐量、利用率、并发
请求是随机到达的,实际来的会比你选的多一点或少一点,利用率和吞吐量也就跟着它变。按秒平均的三个读数从第 5 秒起显示:头几秒的请求太少,平均数会忽高忽低。
每秒请求数和平均用时:每跑完一次 30 秒描一个点
到达的时刻和处理的时长都带随机性,但每次打开都一样,方便比较。容量是平均数:处理时长有长有短,一段时间里完成的请求可能略多于每秒 50 个。平均用时只算已经完成的请求;失败的请求离开队伍,不再占用服务器。按模型推算的倍数只说明「先缓后急」的趋势,真实的系统不一定符合模型的假设。
图里的几个读数各说一件事:
- (load):送来的工作是容量的几成。每秒来 45 个、容量 50 个,负载就是 90%。它和(utilization),即服务器忙碌的时间所占的比例,没过载时差不多;过载以后,负载超过 100%,利用率最多只到 100%,多出来的只能排队。
- (throughput):每秒实际完成多少个请求。它不会多于到达的;到了容量附近,就不再跟着上涨。
- (concurrency)数:此刻已经到达、还没完成的请求有几个,正在处理的和排队的都算。
多跑几次就会看到,等待不是匀速变长的:负载 50% 时,平均用时约 40 毫秒;80% 时约 100 毫秒;90% 时约 200 毫秒。按最简单的一种排队模型推算,负载 50% 时,平均用时是不用排队、只算处理的 20 毫秒的 2 倍,80% 时 5 倍,90% 时 10 倍。原因在于请求是随机来的:负载低时,服务器空闲的时间多,偶尔扎堆来的一阵很快就处理完;越接近容量,空闲越少,扎堆来的请求消化不完,队伍只会越积越长。
每秒请求数超过容量以后,多出来的请求每秒都在排队,队伍越排越长,等得太久的请求开始失败:这就是(overload)。
这像只开了一个收费口的收费站:每辆车交费都要一点时间,车流越接近收费口能放行的上限,后面的队伍涨得越快。这个比方有一处不成立:排在收费口前的车,等得再久也只能接着等;请求排队太久就算失败,读者收不到菜谱页。
代价是什么
要让等待不急剧变长,服务器平时就不能太忙,负载要比 100% 低一截。多留出来的容量平时闲着,也要花钱:留得多,高峰时从容,平时浪费;留得少,省钱,高峰一来就过载。
过载还有一个隐蔽的代价:读者等不下去关掉页面,他的请求却可能还在排队,服务器照样把它处理完。这时每秒处理完的请求并不少,其中有用的却越来越少,亚马逊的一篇工程文章就描述过这样的过程(2019)。过载也不罕见:手机游戏 Pokémon GO 2016 年上线以后,涌来的访问量达到当初目标的 50 倍,游戏的稳定性随之出了问题(Google Cloud 博客,2016)。
后面几章各讲一种应对:几台服务器一起分担(第 4 章),不必马上做完的事放进队列慢慢做(第 7 章),挡住发得过多的请求者(第 11 章),快撑不住时主动拒绝一部分请求(第 12 章)。最直接的办法,是换一台更强的电脑。
资料来源
以下资料均于 2026-10-22、2026-10-23 和 2026-10-25 访问。