去年夏天我帮一个朋友调试工厂的供水系统,那台管道泵在每次启动的瞬间,压力表指针直接打到红色区域,把后面的一个压力传感器震坏了。换传感器的时候我突然意识到,这东西跟我在机房看到的网络流量曲线几乎一模一样——平时安安静静,一到某个时刻就像憋了很久的水突然冲出来,形成尖锐的峰值。后来我查了资料,发现这种现象在流体力学里叫水锤效应,在网络工程师眼里叫突发流量,本质上都是同一种东西:脉冲流量。
先说说物理世界里的脉冲流量。水锤效应的经典公式是 ΔP = ρ · c · Δv,其中ρ是水的密度(约1000kg/m³),c是管道内压力波速(钢管里大约1200m/s),Δv是流速变化量。如果一条管道里水流速度原来是2m/s,阀门在0.1秒内完全关闭,那么压力增量差不多就是1000×1200×2 = 2.4MPa,也就是24个大气压。普通钢管都顶不住这种瞬间冲击。解决办法也直接:要么延长关闭时间,要么在阀门附近加装蓄能器或气囊。蓄能器的原理很简单,就是给脉冲一个缓冲空间,让它慢慢释放。
再来看网络世界。我负责的一台核心交换机上,每天早晚高峰都会出现丢包。抓包一看,某个业务服务器每隔几分钟就会发出一阵高达900Mbps的突发流量,而它的平均带宽只有200Mbps。用华为的设备举例,路由器上配置流量整形时,需要设置CIR(承诺信息速率)、CBS(承诺突发尺寸)、PBS(峰值突发尺寸)。CBS通常是CIR的1/8或者1/16,比如CIR设为100Mbps,CBS默认是12.5Mbit。如果突发超过了CBS,多余的包就会被丢弃或标记为红色。我以前总以为调大CBS就能解决问题,后来发现如果CBS调得太大,反而会把突发全部放过去,引起下游更严重的拥塞。真正要做的,是识别哪些流量必须突发(比如TCP慢启动),哪些是非必要的。
有意思的是,我后来把水管里的蓄能器思路用到了网络配置上。在服务器前面加了一层流量整形队列,就好比把硬管改成了软管。我给Nginx所在的主机配了一个基于令牌桶的限速,速率设为150Mbps,突发容量设为20Mbit,这样即使上游突发到900Mbps,经过整形之后也只会以150Mbps的速率平稳输出,同时令牌桶允许短时间积攒最多20Mbit的突发,业务高峰也不会完全被砍掉。效果立竿见影:丢包率从3%降到了0.1%,视频会议不再卡顿。这个案例让我相信,不管是水还是数据,对抗脉冲流量的核心从来不是“消灭突发”,而是“提供一个合理大小的缓冲,把尖峰磨平”。
说了这么多,最后给点实际排查建议吧。如果你是做网络运维的,下次看到接口流量曲线出现锯齿状脉冲,别急着加带宽,先用wireshark抓包看是哪个协议、哪个源IP在产生突发。如果是TCP SYN洪峰,那就是有人扫描;如果是视频流,那可能是编码器关键帧带来的瞬时大包。如果你是做水暖或者工业管道系统的,看到压力表指针乱跳,先计算一下ΔP,再考虑加装蓄能器或者使用电控阀门延长动作时间。记住一个数字:脉冲进入系统的能量,最终必须被某个组件吸收,要么缓冲器,要么你的设备和管道本身。选择后者,代价往往很贵。