2. OTA基础概念
聊到OTA升级,很多人第一反应就是“把新固件发到设备上”。其实没那么简单。一个真正能上生产环境的OTA系统,至少得有四块拼图:云端管理平台、CDN分发网络、终端升级代理,以及升级策略本身——差分还是全量。
我最早做智能家居网关OTA时,就犯过一个低级错误:只搭了个HTTP服务器让设备拉文件。结果1000台设备同时升级,服务器直接挂了,用户家里的网关变砖了一整天。嗯,从那以后我才真正理解,架构设计不是堆功能,而是把每个环节的流量、可靠性、容错都想清楚。
2.1 云端管理平台:升级的大脑
云端管理平台是整个OTA系统的指挥中心。它不负责传文件,但负责决定“谁、什么时候、升级到什么版本”。
我个人习惯把平台拆成三个核心模块:
- 设备管理模块:维护设备清单、当前版本、分组标签。比如“华东区-智能灯-批次A”。
- 升级策略引擎:灰度比例、分批间隔、回滚条件。说白了就是“先放5%的设备试试水,没问题再全量”。
- 任务调度与监控:下发升级指令,跟踪每台设备的进度、成功/失败状态。
关键指标:一个成熟的平台,单机QPS至少能扛5000+的设备状态上报。我见过某厂商用单线程轮询数据库,设备量一过万就卡死——这就是架构没想清楚。
你想想看,如果平台挂了,升级任务发不出去,设备永远收不到通知。所以平台本身要做高可用,数据库主从、服务多副本、接口幂等,这些都是基本功。
2.2 升级包分发网络(CDN):别让流量压垮你
升级包怎么送到设备手里?直接让设备从云平台下载?千万别。几十MB的固件,一万台设备同时下载,带宽费用能让你哭出来。
正确的做法是:平台只下发下载地址(URL),设备去CDN拉文件。
| 对比项 | 直连云平台下载 | CDN分发 |
|---|---|---|
| 带宽成本 | 高(源站带宽贵) | 低(边缘节点便宜) |
| 并发能力 | 受限于服务器 | 弹性扩展 |
| 地域覆盖 | 依赖单点 | 全球就近接入 |
| 升级包更新 | 实时替换 | 需刷新缓存 |
我曾经帮一家车联网公司排查过升级慢的问题。他们的设备分布在全国各地,但升级包只放在一个华东机房。结果新疆的设备下载速度不到10KB/s。后来切到CDN,速度直接飙到2MB/s。说白了,物理距离就是延迟,CDN就是帮你把文件“搬”到用户家门口。
避坑指南:CDN缓存刷新有延迟。如果你紧急修复了一个bug,重新上传升级包后,设备可能还在下载旧包。我建议在URL里加版本号或时间戳,比如 https://cdn.example.com/firmware/v2.1.3.bin,强制CDN回源。
2.3 终端设备升级代理(Agent):最后一公里的守护者
Agent跑在设备上,是升级指令的最终执行者。它要干的事不少:
- 接收指令:从MQTT/CoAP/HTTP通道拿到升级通知。
- 下载校验:从CDN拉包,校验MD5/SHA256,防止文件损坏或被篡改。
- 备份当前固件:万一升级失败,还能回滚。
- 写入新固件:擦写Flash分区,更新Bootloader指针。
- 上报结果:成功或失败,都得告诉平台。
这里有个容易被忽略的点:Agent必须处理断电。设备升级到一半,用户把电拔了怎么办?我见过一个案例,Agent没有做双分区备份,升级中途断电,设备直接变砖。后来他们加了AB分区切换机制——A区跑当前系统,B区写新系统,写完后校验通过才切过去。就算B区写坏了,A区还能正常启动。
注意:Agent的代码要尽量精简。它跑在MCU或低端Linux上,内存和Flash都很有限。我习惯把Agent控制在50KB以内,只保留核心功能,解压缩、校验、写分区。其他花哨功能一律砍掉。
2.4 差分升级与全量升级:选哪个?
这是每次架构评审都会吵起来的话题。我直接说结论:没有银弹,看场景。
全量升级
就是把完整固件包发给设备。简单、可靠、兼容性好。缺点是包大,流量费高,下载时间长。
- 适用场景:首次烧录、跨大版本升级(比如从V1.x跳到V3.x)、设备存储空间充裕。
- 包大小:通常10MB~100MB(视功能而定)。
差分升级
只发送新旧固件之间的差异部分。包小,省流量,升级快。但生成差分包需要算法(bsdiff、hdiffpatch等),而且对设备算力有要求。
- 适用场景:频繁的小版本迭代、物联网低功耗设备、流量敏感场景(比如NB-IoT)。
- 包大小:通常只有全量包的5%~30%。
| 维度 | 全量升级 | 差分升级 |
|---|---|---|
| 包大小 | 大 | 小 |
| 生成复杂度 | 低(直接打包) | 高(需对比新旧文件) |
| 设备端开销 | 低(直接写入) | 中(需解差分、合并) |
| 升级成功率 | 高 | 中(依赖旧版本精确匹配) |
| 流量消耗 | 高 | 低 |
我个人习惯的做法是:默认用差分,兜底用全量。平台先尝试下发差分包,如果设备上报“旧版本不匹配”或“解压失败”,自动回退到全量包。这样既省了大部分流量,又保证了可靠性。
经验之谈:差分升级对版本管理要求很高。你必须保证设备上报的版本号是准确的。我曾经遇到设备上报“V2.0.1”,实际跑的是“V2.0.1-hotfix”,结果差分包打进去直接崩溃。后来我们在差分包生成前,强制校验旧固件的完整哈希,而不是只看版本号。
2.5 整体架构图:把四块拼起来
下面这张图展示了OTA升级系统的核心流程。你可以看到,云端平台、CDN、设备Agent三者如何协作,以及差分/全量两条路径的分支。
从图上你能看到,整个流程是闭环的:平台下发指令 → CDN提供下载 → Agent执行并上报 → 平台根据结果决定下一步。差分和全量不是互斥的,而是互补的。
我的建议:刚开始做OTA架构时,先跑通全量升级,保证链路通了,再引入差分。别一上来就搞差分,否则排查问题时会多一个变量。我当年就是太心急,差分和全量一起上,结果设备下载差分包后解压失败,我花了三天才定位到是旧固件哈希不一致。