CDN节点SA板卡限速:令牌桶原理、配置与排障

发布时间:2026/10/29 17:25:30
CDN节点SA板卡限速:令牌桶原理、配置与排障

CDN行业里聊到“SA板卡限速”,很多刚入行的朋友第一反应是“不就是限个带宽吗”,真到机房里对着那块插在节点服务器上的业务板卡敲命令时,才发现事情没那么简单。SA板卡限速指的是在内容分发节点的专用业务处理板卡上,对经过该板卡的流量做带宽、包速率、并发连接数等维度的约束,让单台节点在承载几十甚至上百个客户域名时,不至于被某一个客户的突发流量拖垮整机出口。它解决的是“资源公平”和“成本可控”这两件在CDN行业里最要命的事。这篇内容适合三类人看:刚接触CDN节点运维、搞不清楚硬件限速和软件限速区别的新人;需要给客户做带宽套餐落地、被限速策略折腾过的运维老手;以及做边缘节点架构设计、要在成本和质量之间找平衡的同行。我会从板卡是什么讲起,一路讲到参数怎么算、配置怎么下、出问题怎么查。

1. CDN节点里的SA板卡到底是个什么东西

1.1 从机柜里那块“多出来的卡”说起

拆开一台CDN边缘节点的机箱,除了常规的CPU、内存、硬盘和网卡,你往往还能看到一块独立的业务板卡,插在特定槽位上,前面板带几个光口,后面板走高速总线跟主机通信。不同厂商对它的叫法五花八门,有叫业务处理卡的,有叫加速卡的,也有直接缩写为SA卡的,常见的解释是Service Application或者Service Accelerator这一类,具体含义各家文档不一样,但功能定位高度一致:把转发、会话管理、限速、统计这些重复度极高又吃性能的活儿,从通用CPU手里接过去。

为什么非要这么干?因为CDN节点的流量模型太特殊了。一台边缘节点对外可能挂着上百个加速域名,每个域名背后对应不同的客户、不同的计费套餐、不同的服务质量约定。如果用纯软件方案在Linux内核里做限速,靠tc命令挂qdisc,几Gbps的量还能撑住,一旦端口跑到25G甚至100G,每秒几千万个数据包涌进来,CPU光处理软中断就满了,限速策略还没执行,业务进程已经饿死了。SA板卡的价值就在这儿:它用专用硬件流水线做流量识别和令牌桶计算,主CPU只需要下发策略和收统计结果,转发路径上的限速动作几乎不占主机的算力。

我见过不少团队一开始图省事,全靠软件限速顶着,节点规模小的时候没感觉,等到单机带宽从10G升到25G,问题集中爆发——限速不准、统计延迟、CPU软中断飙到90%以上,最后还是要回到硬件方案上。这不是说软件限速没用,而是在CDN这种高并发、多租户、大带宽的场景下,纯软件方案的边际成本涨得太快。

1.2 SA板卡和纯软件限速到底差在哪

要理解这个差异,得先搞清楚两者的工作位置不同。软件限速是在协议栈里做的,数据包要先经过网卡驱动、进入内核、被分类器匹配上、再丢进对应的队列,中间每一次内存拷贝、每一次锁竞争都是开销。硬件限速是在板卡的转发流水线里做的,包进来之后查表、命中限速策略、执行令牌桶判断、决定放行还是丢弃,整个过程在几微秒内完成,不需要把包搬到主机内存里转一圈。

这个差别在指标上体现得非常直接。软件方案在高PPS场景下,限速精度会明显漂移,你配置的是100Mbps,实测可能跑到130Mbps也可能只有80Mbps,因为分类和调度本身就要消耗时间片。硬件方案因为流水线是并行的,精度能稳定在配置值的百分之几以内。更关键的是统计维度,软件方案想同时统计带宽、包速率、新建连接数、并发连接数,每多一个维度就多一层匹配开销;板卡上这些计数器往往是并行维护的,多维度统计对转发性能的影响很小。

但硬件方案也不是没有代价。策略下发有延迟,改一条限速规则不像改iptables那样立刻生效,通常要走配置通道下发到板卡,中间有个秒级甚至十几秒的收敛过程。策略表项数量也有上限,一台节点能同时生效的限速规则条目是有限的,超了就得合并或者走兜底策略。还有就是排障难度高,软件限速你还能用tc show看看队列状态,硬件限速很多时候只能看板卡计数器,出问题时的可观测性要差一截。

1.3 为什么CDN场景非要在板卡上做限速

这个问题换个问法就是:不限速行不行?在某些内部测试环境里确实可以,但放到生产环境,不限速的CDN节点基本活不过一个流量高峰。

第一层原因是成本。CDN的商业模式本质上是带宽的批发零售,从上游运营商那里买带宽,按套餐卖给客户。如果某个客户的流量没有约束,他一个域名的大文件下载就能把整台节点的出口打满,其他客户的请求全部受影响,而你收的带宽费是按套餐算的,这笔账直接亏穿。限速是把“共享资源”变成“可计量资源”的手段。

第二层原因是公平性。一台节点上跑几十个客户的业务,谁都想在高峰时段多抢一点带宽。没有限速,先到先得,谁的连接数多谁占优,这对小客户极不公平。有了分层限速,每个客户有自己的带宽上限,超出部分要么被整形排队要么被丢弃,资源分配就有了规则。

第三层原因是防护。CDN节点天然暴露在公网,被刷、被爬、被异常请求打是常态。限速在这时候扮演的是第一道闸门:单IP的连接数限制、单域名的QPS限制、单URL的请求速率限制,能在流量到达业务进程之前就把异常部分拦掉。这些动作如果全放在应用层做,业务进程早就被打挂了。板卡上做的限速更靠近入口,拦截成本更低。

第四层原因跟计费有关。很多CDN套餐是按95峰值计费或者按流量计费,节点侧必须能准确统计每个客户实际用了多少带宽。板卡上的硬件计数器采样精度高、开销小,是计费数据的原始来源之一。限速和统计在板卡上是同一套流水线完成的,这两个功能天然绑在一起。

2. SA板卡限速的核心机制拆解

2.1 令牌桶和漏桶:限速的数学底座

不管界面上的配置项叫什么名字,底层基本都是令牌桶或者漏桶这两个模型之一。令牌桶的思路很直观:有个桶,以恒定速率往里放令牌,桶有容量上限,满了就溢出。每个数据包要发出去,得先从桶里拿走对应数量的令牌,拿不到就排队或者丢弃。这个模型的好处是允许突发——只要桶里攒了令牌,短时间内可以超过平均速率发一波,突发完之后又回落到平均速率。

漏桶则是另一个视角:请求先进入一个队列,队列以恒定速率往外漏,队列满了就丢。漏桶的输出是绝对平滑的,不允许突发。CDN场景里更常用的是令牌桶,因为Web流量本身就不是匀速的,页面加载、视频起播、文件下载的头部都有明显的突发特征,用漏桶会把这些正常突发削掉,体验反而变差。

工程上更常见的是双速三色标记模型,也就是常说的trTCM。它同时维护两个速率:承诺速率CIR和峰值速率PIR,配上两个桶深CBS和PBS。数据包进来先看是否超过峰值,超了标红直接丢;没超峰值再看是否超过承诺速率,超了标黄,允许在拥塞时优先丢弃;都没超标绿正常转发。这套模型在板卡上是通过流水线里的比较器和计数器实现的,每一级判断只需要几个时钟周期。

提示:配置界面上如果只让你填一个“限速值”,那多半是单速单桶的简化模型,突发容忍度很低。如果看到CIR/PIR/CBS/PBS四组参数,说明背后是双速三色,策略空间更大,但也更容易配错。

2.2 多级限速:端口、队列、租户、URL各有各的闸

CDN节点上的限速从来不是单层的,而是嵌套的多级结构。最外层是物理端口或者子接口级别的限速,这一层通常跟着上游链路的带宽走,比如一条25G链路,端口限速可能设在23G左右留一点余量。这一层的作用是防止整机出口被彻底打满导致链路层丢包,属于兜底。

往下一层是租户级或者VLAN级限速,对应到具体的客户。这一层直接对应商务套餐,客户买的是100Mbps,这里就配100Mbps。这一层是计费和公平性的核心,配置错误的影响也最大——配低了客户投诉,配高了公司亏钱。

再往下是业务级限速,比如回源带宽限制、单域名QPS限制、单URL并发限制。回源限速的目的是保护源站,很多客户的源站承受能力有限,边缘节点回源太猛会把源站打挂,所以要在出方向做约束。QPS和并发限制则是防盗刷、防爬虫的手段。

最细的一层是会话级,比如单IP的最大并发连接数、单IP的新建连接速率。这一层通常不叫“限速”,而叫“连接数控制”,但底层用的还是令牌桶那一套,只是令牌的单位从字节换成了连接数。

这四层是叠加生效的,一个包要同时通过四道闸才能出去。这里有个很常见的误区:以为配了租户级限速就够了,结果端口级没配,某个客户的突发流量把整条链路打满,其他客户跟着遭殃。多级的意义就在于每一级负责不同粒度的保护,缺一层就有一个漏洞。

2.3 硬件卸载与带宽、包速率、连接数三线并行

板卡做限速最核心的优势是并行。带宽限速看的是字节数,包速率限速看的是包个数,连接数限制看的是会话表项。这三个维度在软件方案里往往是串行判断的,先查带宽再查包速率,多一步就多一份延迟。板卡上的流水线可以把这三个判断并行展开,一个包进来同时过三个计数器,任何一个超标就触发对应动作。

这里要特别说清楚带宽和包速率为什么要分开限。很多新手觉得限了带宽就够了,其实不然。同样100Mbps的带宽,全是大包的话每秒大概几千到一万个包,全是小包的话可能到十几万PPS。如果只限带宽不限包速率,攻击者用大量小包打过来,带宽计数器还没到阈值,转发芯片的包处理能力已经被打满了。所以生产环境里通常是带宽和PPS双限,取先到的那个阈值。

举个数:假设端口是25G,线速小包(64字节净荷,加上前导码和帧间隙实际占84字节)对应的包速率大约是 25 × 10^9 ÷ (84 × 8) ≈ 37.2 Mpps。如果板卡的包处理能力上限是30Mpps,那PPS限速就得设在30Mpps以下,哪怕带宽远没跑满。这个换算在规划阶段一定要算清楚,不然限速策略配下去,设备先趴了。

连接数维度也是同理。会话表是有容量上限的,一台节点可能只有几百万条会话表项,如果某个客户用短连接疯狂刷,表项很快被占满,新用户连不进来。所以并发连接数和新建连接速率这两个指标,在大流量节点上是必配项。

限速维度计量单位主要保护对象典型配置位置
带宽bps出口链路、计费准确性端口、子接口、租户
包速率pps转发芯片处理能力端口、队列
并发连接数条会话表容量租户、源IP
新建连接速率cps会话建立能力源IP、目的域名
请求速率qps业务进程、源站域名、URL

3. 实操:一次SA板卡限速的配置与验证

3.1 上线前的基线测量,不做这步等于瞎配

配置限速之前最忌讳的事情是拍脑袋填数字。我见过太多案例,运维照着套餐文档把100Mbps填进去,结果客户投诉速度只有80Mbps,查了半天发现链路上还有各种开销。所以第一步永远是测量基线。

基线测量要测三样东西:空载时的链路能力、满载时的实际吞吐、以及小包场景下的PPS上限。链路能力用打流工具压一下,看看单条流能跑到多少,多条流并发时能不能接近线速。满载吞吐要注意区分单向和双向,很多链路标称25G是双向合计还是单向,文档上写得含糊,实测最准。PPS上限则要用小包打,看看板卡在什么包速率下开始出现计数丢包。

测量的时候有个细节容易被忽略:打流的时间要够长。短时间的打流会被令牌桶的突发容量吃掉,看起来跑满了,实际稳态速率差很远。我的习惯是至少打60秒,前10秒当预热不计入统计,后面取稳定段的平均值。另外要多轮测量取中位数,单次结果受背板拥堵、其他业务干扰的影响很大。

还有一点,测量要在业务低峰期做。CDN节点的流量有明显的时段特征,晚上八点到十一点是高峰,凌晨是低谷。在高峰期做基线测量,测出来的数字是被其他业务挤压过的,不能代表真实能力。这个坑我踩过一次,凌晨测出来能跑23G,白天按这个数字配了限速,结果高峰期一片投诉,重新测发现实际只能稳定在19G左右。

3.2 参数怎么算:从带宽数字到令牌桶尺寸

拿到基线数据之后,就进入参数计算环节。这里以最常见的双速三色为例,把计算过程拆开讲。

先定CIR,也就是承诺速率。这个数字来自客户的套餐,比如100Mbps。但要注意单位换算,配置界面上可能是bps、kbps或者Mbps,填错一个数量级就是灾难。我习惯统一换算成bps再填,100Mbps就是100000000,不要写成100000或1000。

再定PIR,峰值速率。这个通常是CIR的1.2到1.5倍,给正常突发留空间。为什么不能设成和CIR一样?因为Web流量天然有突发,页面加载时会同时发起几十个请求,如果PIR等于CIR,这些请求会被大量整形排队,首屏时间明显变长。设在1.2倍左右是个经验值,既能容忍正常突发,又不至于让客户长期超用。

然后是桶深CBS。桶深决定了允许多大的突发量,计算公式是 CBS = CIR × 突发容忍时间。突发容忍时间取多少合适?太小了突发被削掉,太大了等于变相放宽了限速。CDN场景下常见的取值是10到100毫秒。举个具体例子:CIR是100Mbps,突发容忍时间取50毫秒,那么 CBS = 100 × 10^6 ÷ 8 × 0.05 = 625000 字节,约610KB。这个桶深意味着客户可以在50毫秒内以满速发完610KB的数据,超过这个量就得按平均速率走了。

PBS的算法类似,用PIR乘以同一个突发容忍时间。上面例子里PIR是120Mbps,PBS = 120 × 10^6 ÷ 8 × 0.05 = 750000 字节,约732KB。

计算过程看起来简单,但有两个地方特别容易出错。一个是单位,比特和字节混用是高频事故,100Mbps是12.5MB/s,不是100MB/s,差了8倍。另一个是突发容忍时间的选取要跟业务类型匹配,点播大文件下载可以取大一点,因为TCP本身有拥塞控制,短时突发不会造成问题;而API类小请求业务要取小一点,否则突发流量会掩盖真实的QPS压力。

参数含义计算方式示例值(CIR=100Mbps,PIR=120Mbps,突发50ms)
CIR承诺速率来自套餐100 Mbps
PIR峰值速率CIR × 1.2120 Mbps
CBS承诺突发桶深CIR ÷ 8 × 突发时间625000 字节
PBS峰值突发桶深PIR ÷ 8 × 突发时间750000 字节

3.3 配置下发与验证,每一步都要留证据

配置下发这一步,不同厂商的板卡命令行风格差异很大,但逻辑是相通的:先定义分类规则匹配流量,再定义限速策略绑定参数,最后把策略应用到接口或者租户上。下面给一段示意性的配置流程,语法是通用的伪代码风格,实际使用时按你手头设备的文档替换。

# 第一步:定义流量分类,按VLAN匹配租户 class-map tenant_1001 match vlan 1001 # 第二步:定义限速策略,绑定双速三色参数 policy-map limit_1001 class tenant_1001 police cir 100000000 pir 120000000 conform-action transmit exceed-action mark-yellow violate-action drop # 第三步:应用到接口入方向 interface eth1/1 service-policy input limit_1001 # 第四步:确认下发状态 show policy-map interface eth1/1

配置下去之后别急着收工,必须验证。验证分三个层次。

第一层看策略是否生效。用show命令查接口的策略状态,确认命中计数在涨。如果计数一直不动,说明分类规则没匹配上,回头查VLAN号、查接口方向、查策略有没有真正加载到板卡。

第二层看限速精度。用小流量打一下,比如配100Mbps,先用80Mbps打30秒,应该零丢包;再用120Mbps打30秒,应该看到部分丢包或者标记。如果80Mbps就开始丢,说明桶深或者参数配错了;如果120Mbps还不丢,说明策略根本没生效。

第三层看业务影响。限速配下去之后,实际业务的响应时间、成功率有没有变化。这一步最容易被跳过,但恰恰最重要。限速策略正确不代表业务体验没受影响,特别是回源限速和QPS限速,配得激进一点就可能把正常请求误杀。

验证过程一定要留证据:打流工具的日志、show命令的输出截图、业务监控的曲线。出了纠纷的时候,这些是唯一能说清楚问题的东西。我吃过一次亏,配完没截图,后来客户投诉限速不准,双方各执一词,最后只能重配一遍重新测。

注意:策略下发到板卡是有收敛时间的,通常几秒到几十秒不等。下发后立刻验证可能会看到旧策略还在生效,建议等一分钟再测,或者用板卡的策略版本号确认已经切换。

4. 常见问题与排查技巧实录

4.1 典型故障速查表

限速相关的故障有个共同特点:现象看起来很相似,原因却千差万别。下面这张表是我这些年攒下来的高频问题对照,遇到问题时先按现象定位到可能的原因,再逐一排除。

现象可能原因排查方向处理方式
限速完全不生效分类规则未命中查策略命中计数是否为0核对VLAN、接口方向、五元组
限速值偏高单位填错或PIR未生效查配置中的数值和单位统一换算成bps重新下发
限速值偏低桶深太小或突发时间设太短查CBS/PBS计算按业务类型调整突发时间
限速后丢包严重多级限速叠加过紧逐层拆解各层限速值放宽内层或调整优先级
统计数字对不上采样周期不同步对比板卡计数与业务侧统计统一采样间隔,注意时间窗口对齐
改配置不生效策略未下发到板卡查策略版本号重新下发或重启板卡业务进程
白天正常晚上异常高峰期链路拥塞叠加限速查高峰期基线下调限速值留出余量
小包场景被打满只限带宽未限PPS查包速率计数补充PPS限速

4.2 踩坑实录:那些文档里不会写的事

第一个坑是“限速和TCP的互动”。有次给一个客户配100Mbps限速,配完客户反馈下载速度只有60Mbps。查配置没问题,打流测也正常。后来抓包才看明白:限速策略在超过阈值时是丢包,而TCP把丢包当成拥塞信号,立刻收缩拥塞窗口,然后慢慢重传,速度就上不去了。这是限速和TCP拥塞控制之间的天然冲突,不是配置错误。

解决办法得看场景。如果是大文件下载类业务,把限速从“丢弃”改成“整形排队”会好很多,包不丢只延迟,TCP不会误判拥塞,吞吐能稳住。整形的代价是增加延迟,对延迟敏感的业务又不合适。所以限速动作选丢弃还是整形,要跟着业务类型走,不能一刀切。

第二个坑是“多级限速的内耗”。某次给客户配了租户级100Mbps,同时端口级设了每租户最多50Mbps的保护,本意是防止单客户抢占,结果客户只能跑到50Mbps。查了半天才反应过来,端口级的那个保护策略其实是更紧的约束,优先级还更高。多级限速一定要把每一层的数值列出来对比,取最紧的那个作为实际生效值,配置前就该算清楚。

第三个坑是“统计口径不一致”。板卡上的带宽计数是从接口维度统计的,包含了二层帧头、前导码、帧间隙这些开销;业务侧的统计往往是应用层字节数。两者之间大概有百分之几到十几的差距,具体取决于包长分布。做过一次故障复盘,客户按应用层数字说我们多计费,最后把两层统计同时拉出来对比,才把这个口径差解释清楚。后来我们在客户后台明确标注了统计口径,这类争议就少了很多。

第四个坑是“策略表项耗尽”。板卡能同时生效的限速策略条目是有上限的,节点上客户数量一多,加上各种临时的防护策略,很容易触顶。表项满了之后,新下发的策略要么被拒绝,要么走兜底策略,表现就是“明明配了限速但不生效”。这个问题的隐蔽之处在于报错不一定显式抛出,有时候只是日志里一行不起眼的告警。日常巡检要盯住策略表项的使用率,超过70%就该规划扩容或者合并策略了。

第五个坑是“回源限速把源站保护变成了源站拖累”。回源限速的初衷是保护源站,但如果配得太紧,回源带宽不够,边缘缓存命中率下降,更多请求要回源,反而加剧了回源压力,形成恶性循环。回源限速的数值应该根据源站的实际承载能力和缓存命中率动态调整,而不是拍一个固定值。我的做法是先不配限速跑一周,观察回源带宽的峰值和均值,再在这个基础上留30%余量设定阈值。

4.3 日常巡检该盯哪些指标

限速策略配好不是终点,日常巡检才是保证长期稳定的关键。我一般盯四组指标。

第一组是各层限速的命中率。租户级限速的命中率高,说明这个客户经常超用,要么是套餐买小了,要么是有异常流量,需要跟进。端口级限速的命中率高,说明整机出口压力大,要考虑扩容或者做流量调度。

第二组是丢弃和整形的比例。丢弃比例突然升高,往往意味着有攻击流量或者突发业务上线。整形队列深度持续很高,说明限速值和实际流量不匹配,该调了。

第三组是策略表项和会话表的使用率。这两个都是硬上限资源,用满了就是故障。设置一个70%的告警阈值,提前介入。

第四组是限速前后的业务指标对比。响应时间、成功率、首字节时间这些,限速策略的任何调整都应该在这组指标上有体现。如果调了限速但业务指标毫无变化,要么是策略没生效,要么是这层限速压根不是瓶颈。

巡检周期上,核心指标做成实时看板,异常自动告警;策略配置做每日快照比对,防止有人误改;全量参数核对每周做一次。这个节奏是我试过几次之后定下来的,太频繁浪费人力,太稀疏容易漏掉渐进式的配置漂移。

说到底,SA板卡限速这个事儿,技术本身不算特别复杂,难的是把参数算准、把层次理清、把验证做扎实。我个人的体会是,每次配限速之前先把三件事想明白:这个限速要保护谁、最紧的约束在哪一层、配错了怎么快速回滚。想清楚这三点,后面敲命令和下参数都不会慌。至于那些踩过的坑,大多是当时图快跳过了基线测量或者验证环节,回头补的功夫比一开始认真做要多得多。