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跑在设备上,是升级指令的最终执行者。它要干的事不少:

  1. 接收指令:从MQTT/CoAP/HTTP通道拿到升级通知。
  2. 下载校验:从CDN拉包,校验MD5/SHA256,防止文件损坏或被篡改。
  3. 备份当前固件:万一升级失败,还能回滚。
  4. 写入新固件:擦写Flash分区,更新Bootloader指针。
  5. 上报结果:成功或失败,都得告诉平台。

这里有个容易被忽略的点: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三者如何协作,以及差分/全量两条路径的分支。

OTA升级系统架构图 OTA升级系统核心架构 云端管理平台 设备管理 / 策略引擎 任务调度 / 监控 CDN分发网络 边缘节点缓存 就近下载 / 弹性扩容 终端设备Agent 下载校验 / 备份回滚 AB分区 / 状态上报 下发URL 下载包 上报进度/结果 升级策略决策:差分升级 vs 全量升级 差分升级 bsdiff生成差分包 设备端解差分+合并 全量升级 直接下发完整固件 设备端直接写入 失败回退 💡 核心原则 平台负责策略,CDN负责传输,Agent负责执行 差分优先,全量兜底,确保升级成功率和流量成本的平衡

从图上你能看到,整个流程是闭环的:平台下发指令 → CDN提供下载 → Agent执行并上报 → 平台根据结果决定下一步。差分和全量不是互斥的,而是互补的。

我的建议:刚开始做OTA架构时,先跑通全量升级,保证链路通了,再引入差分。别一上来就搞差分,否则排查问题时会多一个变量。我当年就是太心急,差分和全量一起上,结果设备下载差分包后解压失败,我花了三天才定位到是旧固件哈希不一致。