4、流量整形原理:漏桶算法、令牌桶算法、整形与监管的区别、车载场景下的整形需求
各位好,我是老K。今天咱们聊聊流量整形。说实话,这个知识点在车载网络里特别容易被忽视,但恰恰又是决定通信质量的关键一环。
我刚开始做车载项目时,总觉得流量整形是IT领域的事,跟咱们汽车电子关系不大。直到有一次,一台ADAS样车在高速测试时,摄像头数据流突然把CAN总线给冲垮了——嗯,从那以后我再也不敢小看流量整形了。
4.1 漏桶算法:最朴素的限流思路
漏桶算法,说白了就是一个带漏洞的水桶。你往桶里倒水,不管倒得多快,水从底部漏出去的速度是恒定的。如果桶满了,多余的水就溢出去,丢掉。
在车载网络里,漏桶算法怎么用?我举个例子:
// 漏桶算法的简化实现
class LeakyBucket {
int capacity; // 桶容量(最大突发量)
int leakRate; // 漏出速率(字节/毫秒)
int waterLevel; // 当前水位
long lastTime; // 上次漏水时间
bool sendPacket(int packetSize) {
long now = getCurrentTime();
// 先漏水:根据时间差计算漏掉了多少
int leaked = (now - lastTime) * leakRate;
waterLevel = max(0, waterLevel - leaked);
lastTime = now;
// 检查桶是否还能装下这个包
if (waterLevel + packetSize <= capacity) {
waterLevel += packetSize;
return true; // 允许发送
} else {
return false; // 丢弃或缓存
}
}
};
这个算法的好处是简单、稳定。输出速率绝对平滑,不会出现忽快忽慢的情况。我在做车载以太网AVB流整形时,就经常用这个思路来保证音视频流的稳定输出。
4.2 令牌桶算法:更灵活的整形方案
令牌桶算法就聪明多了。它不像漏桶那样死板,而是允许一定程度的突发。怎么做的?
想象一个桶,里面不断有令牌以固定速率往里放。每个数据包要发送,必须先拿到足够数量的令牌。如果桶里有令牌,你就可以一次性拿走很多,实现突发传输。如果令牌不够,那就得等。
// 令牌桶算法的简化实现
class TokenBucket {
int maxTokens; // 最大令牌数(桶容量)
int tokenRate; // 令牌生成速率(个/毫秒)
int currentTokens; // 当前令牌数
long lastTime; // 上次更新时间
bool sendPacket(int packetSize) {
long now = getCurrentTime();
// 先补充令牌
int newTokens = (now - lastTime) * tokenRate;
currentTokens = min(maxTokens, currentTokens + newTokens);
lastTime = now;
// 检查是否有足够的令牌
if (currentTokens >= packetSize) {
currentTokens -= packetSize;
return true; // 允许发送
} else {
return false; // 令牌不足,等待
}
}
};
我个人习惯在车载以太网网关里用令牌桶做流量整形。为什么?因为车载通信有很强的周期性特征——比如传感器数据每10ms发一次,但偶尔会有突发的大包(比如紧急事件触发的诊断数据)。令牌桶能很好地处理这种场景。
4.3 整形与监管的区别:一字之差,天壤之别
很多新手分不清流量整形和流量监管。我刚开始也犯过这个错。其实它们的区别很简单:
| 对比项 | 流量整形(Shaping) | 流量监管(Policing) |
|---|---|---|
| 处理方式 | 缓存+延迟发送 | 直接丢弃或标记 |
| 对延迟的影响 | 增加延迟(缓存导致) | 不增加延迟(直接丢) |
| 适用场景 | 对丢包敏感的场景 | 对延迟敏感的场景 |
| 车载典型应用 | 音视频流、诊断数据 | 安全关键控制信号 |
说白了,整形是「你先等等,我慢慢发」;监管是「超了?直接扔掉,别废话」。
在车载网络里,我一般这样用:
- 整形:用在非安全关键但需要可靠传输的场景。比如OTA升级包、日志数据。这些数据丢了要重传,不如缓存一下慢慢发。
- 监管:用在安全关键的控制信号。比如制动指令、转向指令。这些信号延迟不得,超了就丢,丢了下个周期再发新的。
核心要点:整形和监管不是二选一的关系。我在实际项目中经常把它们组合使用——先监管过滤掉明显违规的流量,再整形平滑剩余的正常流量。这样既保证了安全性,又提高了带宽利用率。
4.4 车载场景下的整形需求:跟IT网络完全不同
你想想看,车载网络跟办公室网络能一样吗?当然不一样。车载场景有几个独特的需求:
4.4.1 确定性延迟要求
车载网络最核心的要求就是确定性。你不能说「大部分情况下延迟小于1ms」,你得说「最坏情况下延迟不超过1ms」。这对整形算法提出了很高的要求。
我做过一个测试:在CAN FD网络上,用漏桶算法做整形,最坏情况延迟比平均延迟大了3倍。后来改用时间感知整形(TAS),才把抖动控制在可接受范围内。
4.4.2 多优先级混合传输
车载网络里,控制信号、传感器数据、音视频流、诊断信息都在同一根线上跑。整形时必须考虑优先级:
- 高优先级(如制动信号):基本不做整形,直接走快速通道
- 中优先级(如传感器数据):做轻度整形,保证带宽但不增加太多延迟
- 低优先级(如日志、OTA):做深度整形,充分利用空闲带宽
4.4.3 带宽资源有限
车载网络的带宽是固定的,不像IT网络可以随时扩容。CAN FD最高也就8Mbps,车载以太网虽然能到100Mbps甚至1Gbps,但跟IT网络的10G、40G比起来还是小巫见大巫。
所以整形时必须精打细算。我习惯的做法是:先做带宽预算,给每个数据流分配一个「硬上限」和「软上限」。硬上限是绝对不能超的,软上限是允许短时间突发的。
4.4.4 温度与老化影响
这个点可能很多人没想到。车载电子器件的工作温度范围很宽(-40°C到125°C),温度变化会影响晶振精度,进而影响整形算法的计时精度。
我曾经在夏天做路试时发现,车内温度到70°C后,令牌桶的速率偏差达到了15%。后来我们加了一个温度补偿模块,才把偏差控制在2%以内。
4.5 小结:选对算法,事半功倍
说了这么多,总结一下我的经验:
- 漏桶算法:适合对输出速率要求绝对平滑的场景,比如音视频流。但要注意它不允许突发。
- 令牌桶算法:适合需要一定突发能力的场景,比如传感器数据+诊断数据的混合流。但要注意控制桶容量。
- 整形 vs 监管:整形保可靠性,监管保实时性。根据业务需求选,也可以组合使用。
- 车载特殊需求:确定性延迟、多优先级、有限带宽、环境适应性——这些是车载网络整形的四大挑战。
最后说一句:流量整形不是万能的。它解决的是「流量过载」的问题,解决不了「带宽不足」的问题。如果带宽本身就差得远,再好的整形算法也白搭。所以,做车载网络设计时,先把带宽预算算清楚,再谈整形策略。
下一章,咱们聊聊具体的车载网络QoS配置实战,包括CAN FD和车载以太网的配置案例。到时候我会分享一些我在项目里踩过的坑,希望对你有帮助。