在CDN这个行当里,下行限速是个容易让人又爱又恨的话题,爱它,是因为它能帮你摁住带宽成本、挡住恶意流量、保住核心用户体验;恨它,是因为一旦配置不当,用户那边就会卡成PPT,投诉电话直接打爆,今天咱不聊那些花里胡哨的调度算法,就说说下行限速这件事本身——它到底在限什么、怎么限、用什么姿势限最合适。
技术概念拆解:限的是“速率”,不是“带宽”
很多人把下行限速理解成“把带宽从100M砍到10M”,这个说法不准确,带宽是水管的粗细,而速率是水流的速度,CDN里的下行限速,本质上是在TCP/IP协议栈或者应用层上,对每个连接(或者每个IP、每个用户)的传输速率做整形,不让它超过你设定的阈值。

下行限速,给CDN出口加一道聪明的阀门
常见的实现机制有两种:漏桶和令牌桶,漏桶算法就像给桶底开个洞,不管上面倒多少水,流出去的速度恒定是洞的大小——适合做严格的限速,但容易让突发流量被“削平”,令牌桶算法则是桶里攒令牌,来了流量就得拿令牌走,桶里没令牌就得等——它允许一定程度的突发,因为桶里能积攒最多N个令牌,在CDN边缘节点上,这两种算法都有人用,但实际效果差异很大。
更底层一点,TCP的拥塞控制窗口(cwnd)和接收窗口(rwnd)也能用来限速,通过修改窗口大小和ACK的节奏,可以控制发送方的发送速率,这种方式的优点是“零拷贝”,不用在应用层缓存数据,但缺点是粒度粗,难以按用户维度精确控制,而且容易被TCP的延迟ACK等机制干扰。
方案对比:三种主流的限速姿势
方案A:单机内核级限速(iptables/tc)
在每个CDN边缘节点的Linux内核里,用tc的htb或tbf队列来限速,优点是非常快,不占应用CPU,对流量整形效果好,缺点也明显:配置复杂,要处理多队列、优先级;在集群里每台机器各自为政,如果用户请求被调度到不同节点,限速效果无法累计,可能今天这个IP被限了,明天换个节点又满速。
方案B:应用层限速(Nginx/OpenResty Lua)
在Nginx层用limit_rate指令或Lua脚本实现,按变量(如$uri、$remote_addr)动态限速,优点是灵活,能结合业务逻辑——比如普通用户限2M,VIP用户限20M;下载限5M,视频流限8M,缺点是占用CPU和内存,因为要在应用层维护每个连接的状态;而且在并发高的时候,Lua脚本的执行开销不能忽略。
方案C:集中式限速(带宽管理平台+调度联动)
把限速策略放在中心,通过P4/DPDK等技术在L4层做统一的流量控制,或者让中心平台下发token到边缘,由边缘执行,优点是能全局控制,比如限制某个客户的“总出口带宽”而不是单连接速率;还支持按域名、按区域、按时间动态调整,缺点是架构复杂,要引入额外的控制和数据面组件,对运维能力要求高。
适用场景:不能一刀切,得看你的业务长啥样
大文件下载/软件分发
这类场景最吃下行带宽,一个热门软件包可能瞬间打满出口,适合用“按IP限速+按连接限速”的组合,比如对单IP限制5M,单连接限制2M,防止一个机房拉着几十条连接把带宽掏空,但要注意,如果用户是在内网用NAT上网,按IP限速可能会误伤,这时最好能结合URL路径或User-Agent做白名单。
视频流媒体
视频最怕卡顿,但也不能让一个4K视频霸占所有带宽,这里更适合用“基于码率的动态限速”,比如根据视频的分辨率设定阈值:1080p限8M,720p限4M,然后通过HLS/DASH的分段传输,在应用层做“按需取流”,注意,TCP层的限速会导致视频播放器缓冲不足,所以最好在边缘节点上做“预取+平滑发送”。
防刷防爬
很多攻击者是靠低慢速下载来消耗你的带宽,或者用多线程拉取资源,这时可以用“令牌桶+IP黑名单”结合,限制单IP的每秒新建连接数和平均速率,一旦触发阈值,就返回503或直接断连,但注意,如果误伤了正常用户,代价很高,所以建议先限速而不是封禁,让用户自己降速后还能继续访问。
成本控制
当业务峰值超出预算时,可以对整个域名或某个区域设置“总出口上限”,这是集中式限速的强项,比如客户预算是100Gbps带宽,那就把全网下行速率限制在95Gbps,留5Gbps余量,但这种做法会牺牲用户体验,适合对价格敏感、对体验不敏感的离线下载类业务。
选型建议:别追求最强,要追求最匹配
明确你的“限速维度”,你是要限制单用户速率,还是限制单节点速率,还是限制整个业务线的总出口?如果只是单用户,Nginx的limit_rate就够了;如果是单节点,tc用起来更靠谱;如果是全局,必须上集中式方案。
考虑动态调整能力,业务流量有高峰低峰,你的限速策略也得能随时改,内核级tc改起来要重载规则,影响现有连接;应用层Lua可以热加载,但要小心性能,如果你们有完善的配置中心,那应用层更好。
第三,别忘了监控和告警,限速不是设置完就完事,你得能看出来“多少请求被限速了”“平均被限速时长多少”“哪些IP被限得最多”,如果这些数据看不见,你根本不知道限速是否合理,更别说调优了。
给个实用建议:启动时用保守阈值,并设置“降速不切断”策略,比如先限制单连接1M,如果用户确实需要更高速率,允许他短暂提升到2M,持续几秒后回落,这样既保护了带宽,又不会让正常用户瞬间失去连接,不要一上来就搞“一刀切”,CDN拼的是细致活,限速就是一把刀,用得好是手术刀,用不好就是杀猪刀。
下行限速的终极目标不是“限”,而是“让有限的带宽发挥最大的价值”,当你的用户抱怨网速慢时,先别急着加带宽,看看是不是你的“阀门”开错了位置。
发表评论