安卓工控机 OTA 升级方案(SpringBoot+MQTT)

一、方案概述

本方案针对第三方采购安卓工控机的 OTA 升级场景,基于 SpringBoot 服务端 + MQTT 通讯 + 工控机本地守护服务 实现,覆盖 "升级触发→包下载→安装→启动检测→失败回滚→状态监控" 全流程,核心目标是:安全可靠、无人干预、业务无感知、故障可恢复,适配工控机无 root / 有限权限、工业环境网络不稳定、业务连续性要求高等特性。

二、核心架构设计

(一)整体架构图

plaintext

复制代码
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│  SpringBoot 服务端  │      │    MQTT 服务器   │      │  安卓工控机客户端  │
├─────────────────┤      ├─────────────────┤      ├─────────────────┤
│ 1. 设备管理模块   │◄────►│ 1. 消息路由     │◄────►│ 1. MQTT 通讯模块  │
│ 2. 升级包管理模块 │      │ 2. 会话持久化   │      │ 2. OTA 核心服务   │
│ 3. 指令下发模块   │      │ 3. 离线消息缓存 │      │ 3. 启动检测守护进程 │
│ 4. 状态监控模块   │      │ 4. 权限控制     │      │ 4. 回滚执行模块    │
│ 5. 日志告警模块   │      │                 │      │ 5. 本地存储管理    │
└─────────────────┘      └─────────────────┘      └─────────────────┘
        ▲                        ▲                        ▲
        │                        │                        │
        ▼                        ▼                        ▼
┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│  文件服务器      │      │  数据库         │      │  本地存储        │
│  (MinIO/NFS)  │      │  (MySQL/PostgreSQL)│      │  - 升级包缓存    │
│  - 存储升级包    │      │  - 设备信息     │      │  - 原版本备份    │
│  - 提供下载URL   │      │  - 升级日志     │      │  - 状态文件      │
│                 │      │  - 包元信息     │      │  - 日志文件      │
└─────────────────┘      └─────────────────┘      └─────────────────┘

(二)核心组件职责

组件 核心职责
SpringBoot 服务端 设备注册 / 认证、升级包上传 / 管理、升级指令下发、状态接收、日志存储、告警触发
MQTT 服务器 负责服务端与工控机的消息传输,保障离线消息缓存、消息可靠送达(QoS=1)
工控机客户端 接收升级指令、下载升级包、备份原版本、执行安装、启动检测、失败回滚、状态上报
文件服务器 存储升级包(避免服务端存储压力),提供 HTTP 下载链接
数据库 持久化设备信息、升级包元信息、升级 / 回滚日志,支持后续追溯与统计

三、前置条件与环境准备

(一)服务端环境

  1. 基础环境:JDK 11+、Maven 3.6+、MySQL 8.0+;
  2. MQTT 服务器:EMQ X/ActiveMQ(支持 MQTT 3.1.1,配置持久化会话、QoS=1);
  3. 文件服务器:MinIO(轻量、支持 HTTP 下载、Range 断点续传);
  4. 网络:确保服务端、MQTT 服务器、文件服务器可被工控机访问(工业内网 / 公网穿透)。

(二)工控机客户端环境

  1. 系统要求:Android 7.0+(兼容低版本 API);
  2. 权限要求:至少具备 REQUEST_INSTALL_PACKAGES(安装 APK)、WRITE_EXTERNAL_STORAGE(存储升级包 / 备份)、INTERNET(MQTT/HTTP 通讯)权限;若需静默安装 / 回滚,需厂商提供系统签名(无需 root);
  3. 存储要求:预留≥2 倍于升级包大小的空闲空间(推荐本地存储,避免 SD 卡掉卡);
  4. 预装组件:MQTT 客户端、OTA 核心服务、启动检测守护进程(按前文方案实现)。

四、详细流程设计(全链路 Step-by-Step)

阶段 1:系统初始化与设备注册

1. 设备注册(首次联网触发)
  • 工控机启动后,OTA 核心服务自动初始化,通过 MQTT 连接服务器(客户端 ID = 设备 SN 码,username=SN 码,password=MD5 (SN + 盐值));

  • 工控机上报设备基础信息(主题:ota/device/{deviceSn}/register),消息体:

    json

    复制代码
    {
      "deviceSn": "SN_202501010001",
      "deviceModel": "IPC-Android-3288",
      "currentVersion": "V1.0.2",
      "systemVersion": "Android 9.0",
      "ipAddress": "192.168.1.100",
      "hardwareInfo": "CPU:ARM64,RAM:4G,ROM:64G",
      "timestamp": 1734567890000,
      "sign": "md5(deviceSn+timestamp+secret)"
    }
  • 服务端校验设备合法性(SN 码是否已录入系统),校验通过后存储设备信息,返回注册成功响应(主题:ota/server/device/{deviceSn}/resp)。

2. 心跳上报(持续在线)
  • 工控机每 60 秒上报一次心跳(主题:ota/device/{deviceSn}/status),消息体简化为:

    json

    复制代码
    {
      "deviceSn": "SN_202501010001",
      "status": "ONLINE",
      "currentVersion": "V1.0.2",
      "timestamp": 1734567950000,
      "sign": "md5(deviceSn+status+timestamp+secret)"
    }
  • 服务端通过心跳更新设备在线状态,超过 180 秒未收到心跳则标记为 "OFFLINE"。

阶段 2:升级包管理(服务端操作)

1. 升级包上传与审核
  • 管理员通过服务端后台上传升级包(APK 文件),填写元信息:设备型号(适配范围)、目标版本、最低支持版本、MD5 校验码、数字签名、升级描述、维护窗口;
  • 服务端将升级包上传至 MinIO 文件服务器,生成唯一下载 URL,数据库存储包元信息(状态为 "草稿");
  • 管理员审核通过后,升级包状态更新为 "已发布",支持按设备型号、当前版本筛选下发范围。
2. 升级包元信息示例(数据库表结构)
字段名 类型 说明 示例
id BigInt 主键 ID 1001
deviceModel String 适配设备型号(多个用逗号分隔) "IPC-Android-3288,IPC-Android-4418"
version String 升级包版本(语义化) "V2.0.0"
apkUrl String MinIO 下载 URL "http://minio:9000/ota/V2.0.0.apk"
apkSize Long 包大小(字节) 2147483648(2GB)
md5 String MD5 校验码 "e10adc3949ba59abbe56e057f20f883e"
signature String RSA 数字签名(防篡改) "MIIBIjANBgkqhkiG9w0BAQEFAAO..."
minSupportVersion String 最低支持版本(低于则不可升级) "V1.0.0"
maintenanceWindow JSON 维护窗口(开始 / 结束时间戳) {"start":1734576000000,"end":1734583200000}
description String 升级描述 "修复稳定性问题,优化网络传输"
status Integer 状态(0 = 草稿,1 = 已发布,2 = 已下架) 1
releaseTime Long 发布时间戳 1734500000000

阶段 3:升级触发与执行(服务端 + 工控机协同)

1. 升级触发方式
  • 自动触发:服务端按设备型号 + 当前版本筛选目标设备,定时(如凌晨 2 点)下发升级指令;
  • 手动触发:管理员在服务端后台选择单个 / 批量设备,手动下发升级指令;
  • 设备主动查询:工控机每 24 小时主动向服务端请求版本信息(主题:ota/device/{deviceSn}/query),服务端返回是否有可用升级包。
2. 升级指令下发(服务端→工控机)
  • 主题:ota/device/{deviceSn}/cmd

  • 消息体(QoS=1,确保必达): json

    复制代码
    {
      "cmdType": "UPGRADE",
      "upgradeInfo": {
        "targetVersion": "V2.0.0",
        "apkUrl": "http://minio:9000/ota/V2.0.0.apk",
        "apkSize": 2147483648,
        "md5": "e10adc3949ba59abbe56e057f20f883e",
        "signature": "MIIBIjANBgkqhkiG9w0BAQEFAAO...",
        "forceUpgrade": false,
        "maintenanceWindow": {"start":1734576000000,"end":1734583200000},
        "description": "修复稳定性问题,优化网络传输"
      },
      "timestamp": 1734568000000,
      "nonce": "random123456",
      "sign": "md5(cmdType+targetVersion+timestamp+nonce+secret)"
    }
3. 工控机接收指令与预处理
  • 工控机校验指令签名(防篡改),若当前处于维护窗口外且非强制升级,上报 UPGRADE_WAITING 状态(等待维护窗口);
  • 若在维护窗口内,执行原版本备份:
    • 备份内容:当前 APK(路径:/data/local/ota/backup/{deviceSn}_v{currentVersion}_xxx.apk)、核心配置文件(/data/local/ota/backup/config/);
    • 记录备份元信息(版本号、MD5、路径)至本地状态文件(/data/local/ota/state/upgrade_state.json);
    • 备份失败则上报 BACKUP_FAILED(错误码 4),终止升级。
  • 备份成功后,上报 UPGRADE_READY 状态,准备下载升级包。
4. 升级包下载(支持断点续传)
  • 工控机通过 HTTP 下载升级包(存储路径:/data/local/ota/download/new.apk),利用 Range 请求实现断点续传:

    • 首次下载:请求 Range: bytes=0-,开始下载;
    • 网络中断后恢复:读取已下载字节数,请求 Range: bytes=xxx-,从断点继续;
  • 实时上报下载进度(主题:ota/device/{deviceSn}/progress):

    json

    复制代码
    {
      "deviceSn": "SN_202501010001",
      "targetVersion": "V2.0.0",
      "progressType": "DOWNLOAD",
      "progress": 68,
      "downloadedSize": 1460288901,
      "totalSize": 2147483648,
      "timestamp": 1734568500000,
      "sign": "md5(deviceSn+progressType+progress+timestamp+secret)"
    }
  • 下载失败处理:重试 3 次,仍失败则上报 DOWNLOAD_FAILED(错误码 1),终止升级。

5. 升级包校验
  • 下载完成后,工控机计算本地 APK 的 MD5 值,与指令中的 md5 比对;
  • 若配置了数字签名,通过公钥验证 signature(防包被篡改);
  • 校验失败则上报 VERIFY_FAILED(错误码 2),删除下载的 APK,终止升级。
6. 静默安装升级包
  • 工控机执行安装命令(需系统签名,无需 root): bash

    运行

    复制代码
    pm install -r -d /data/local/ota/download/new.apk  # -r=覆盖安装,-d=允许降级(后续回滚用)
  • 安装过程中每 10 秒上报进度(progressType=INSTALL,进度 70%-90%);

  • 安装失败处理:重试 2 次,仍失败则上报 INSTALL_FAILED(错误码 3),触发回滚。

7. 安装完成重启
  • 安装成功后,工控机自动重启(reboot 命令),重启前更新本地状态:currentState="REBOOT_AFTER_INSTALL"
  • 重启后,启动检测守护进程自动激活(阶段 4 核心流程)。

阶段 4:启动检测与失败回滚

1. 启动检测(守护进程执行)

按前文定义的 5 个维度检测新 APK 启动状态,任一维度触发失败阈值则判定 "启动失败":

  • 30 秒内进程未存在→失败;
  • 60 秒内进程闪退≥2 次→失败;
  • 40 秒内业务端口未监听→失败;
  • 20 秒内健康检查失败→失败;
  • 90 秒内未上报 APP_START_SUCCESS 心跳→失败。
2. 启动成功处理
  • 检测通过后,工控机上报 APP_START_SUCCESS 状态(主题:ota/device/{deviceSn}/status),更新本地状态为 UPGRADE_SUCCESS
  • 服务端接收状态后,更新设备当前版本为目标版本,记录升级成功日志,清理设备备份(保留最近 3 个版本)。
3. 启动失败回滚(自动触发)
  • 检测守护进程生成启动失败报告,捕获启动日志,调用回滚脚本;
  • 回滚步骤(详细见前文):
    1. 预处理:停止新 APK 进程、释放端口、清理残留;
    2. 备份校验:检查原版本备份文件存在性 + MD5 一致性;
    3. 安装原版本:执行 pm install -r 备份路径
    4. 恢复配置:将备份的配置文件复制回原路径;
    5. 重启验证:重启工控机,检测原版本启动状态;
    6. 状态上报:回滚成功上报 ROLLBACKED,失败上报 ROLLBACK_FAILED(错误码 7-11)。
  • 服务端接收回滚状态后,触发告警(短信 / 邮件),锁定该升级包(禁止自动下发),等待管理员排查问题。

阶段 5:监控、日志与告警(服务端核心能力)

1. 全流程日志记录
  • 服务端日志:记录指令下发时间、设备状态变更、升级 / 回滚结果、错误原因,存储周期≥90 天;
  • 工控机日志:记录下载进度、安装日志、启动检测日志、回滚日志,支持通过 MQTT 上传至服务端(主题:ota/device/{deviceSn}/log/upload)。
2. 实时监控面板

服务端后台提供可视化监控:

  • 设备状态统计:在线 / 离线设备数、升级中 / 待升级 / 已升级设备数;
  • 升级进度统计:各设备下载进度、安装进度、回滚进度;
  • 成功率统计:升级成功率、回滚成功率、失败原因分布(如下载失败占比、启动失败占比)。
3. 告警机制

触发以下场景时,服务端发送告警(支持短信、邮件、后台弹窗):

  • 升级失败:设备升级过程中上报 FAILED 状态;
  • 回滚失败:上报 ROLLBACK_FAILED 状态(尤其是原版本也启动失败);
  • 批量异常:同一升级包下发后,启动失败率≥5%;
  • 设备离线:关键设备离线超过 30 分钟。

五、关键技术保障

(一)通讯可靠性

  1. MQTT 配置:cleanSession=false(保留会话)、QoS=1(升级 / 回滚指令)、keepAliveInterval=60s(心跳);
  2. 离线消息:MQTT 服务器缓存离线期间的指令,设备重连后自动接收;
  3. 消息重试:工控机上报状态失败时,缓存消息,重连后自动重试(最多 3 次);
  4. 遗嘱消息:工控机设置遗嘱(willTopic=ota/device/{deviceSn}/statuswillMessage={"status":"OFFLINE"}),服务端快速感知设备离线。

(二)数据安全性

  1. 身份认证:设备连接 MQTT 时通过 username/password(SN + 密钥)校验,服务端仅允许合法设备连接;
  2. 消息防篡改:所有指令 / 状态上报均携带 MD5 签名(含密钥),接收方校验后再处理;
  3. 升级包防篡改:通过 MD5 校验 + RSA 数字签名双重保障,避免包被替换 / 篡改;
  4. 权限控制:工控机仅授予 OTA 服务必要权限,避免过度授权;服务端按角色分配权限(如管理员可下发指令,操作员仅可查看监控)。

(三)工业环境适配

  1. 断点续传:下载升级包支持 HTTP Range 请求,应对工业网络中断频繁问题;
  2. 维护窗口:升级 / 回滚仅在维护窗口内执行(可配置),避免业务高峰期中断;
  3. 低资源占用:工控机 OTA 服务 + 守护进程内存占用≤20MB,CPU 占用≤5%,不影响业务运行;
  4. 断电保护:工控机本地状态文件实时更新,断电后重启可恢复之前的升级 / 回滚进度。

(四)兼容性适配

  1. 系统版本兼容:支持 Android 7.0+,适配 FileProvider(Android 7.0+ 文件访问)、动态权限申请(Android 6.0+);
  2. 设备型号适配:升级包按设备型号筛选下发,避免跨型号升级导致不兼容;
  3. 权限兼容:无 root 时,依赖系统签名实现静默安装;若无法获取系统签名,可协商厂商开放 INSTALL_PACKAGES 权限。

六、部署与测试方案

(一)部署步骤

  1. 服务端部署:
    • 部署 MySQL 数据库(初始化设备表、升级包表、日志表);
    • 部署 MinIO 文件服务器(创建 OTA 存储桶,配置访问权限);
    • 部署 MQTT 服务器(配置持久化、心跳、权限);
    • 部署 SpringBoot 服务(配置 MQTT 连接、数据库连接、MinIO 连接)。
  2. 工控机部署:
    • 预装 OTA 核心服务(APK 形式,开机自启);
    • 预装启动检测守护进程(Native 进程 / 系统服务,按前文方案实现);
    • 配置 MQTT 连接参数(服务器地址、端口、设备 SN、密钥);
    • 初始化本地存储目录(/data/local/ota/download//data/local/ota/backup//data/local/ota/logs/)。

(二)测试方案

  1. 功能测试:
    • 正常升级流程测试:下发合法升级包,验证 "下载→安装→启动成功→状态上报" 全流程;
    • 启动失败回滚测试:按前文方案模拟新 APK 启动失败,验证 "检测→回滚→原版本恢复";
    • 异常场景测试:网络中断、断电、升级包损坏、权限缺失等场景下的流程完整性。
  2. 性能测试:
    • 并发测试:同时向 100 台设备下发升级指令,验证服务端、MQTT 服务器抗压能力;
    • 资源占用测试:监控工控机升级过程中 CPU、内存、网络占用,确保不影响业务。
  3. 兼容性测试:
    • 在目标工控机型号 + 不同安卓版本(如 Android 7.0、9.0、11.0)上验证升级流程。

七、运维与迭代

  1. 日常运维:
    • 定期清理过期日志(服务端 90 天,工控机 30 天);
    • 定期检查升级包存储(MinIO 磁盘空间);
    • 监控 MQTT 服务器、服务端运行状态(如 CPU、内存、连接数)。
  2. 迭代优化:
    • 根据失败原因优化流程(如增加下载重试次数、调整启动检测阈值);
    • 新增功能(如支持升级包差分更新、远程日志调试、批量回滚);
    • 适配新的工控机型号 / 安卓版本。

八、总结

本方案覆盖 OTA 升级全流程,核心优势在于:

  1. 适配第三方工控机:无需 root,依赖系统签名实现静默安装 / 回滚,非侵入式部署;
  2. 故障自动恢复:启动失败后自动回滚,确保业务不中断;
  3. 工业环境适配:断点续传、维护窗口、低资源占用,应对网络不稳定、业务连续性要求高的场景;
  4. 可监控可追溯:全流程日志 + 实时监控 + 告警,便于运维排查问题。

方案可直接落地,若工控机有特殊限制(如无法获取系统签名、文件目录只读),可调整 "安装方式""存储路径" 等细节,确保适配实际场景。

相关推荐
JIngJaneIL1 小时前
智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·论文·智慧物业管理系统
顾林海1 小时前
从0到1搭建Android网络框架:别再让你的请求在"路上迷路"了
android·面试·架构
A3608_(韦煜粮)1 小时前
深入理解 Spring Boot 自动配置:原理、定制与最佳实践摘要
spring boot·自动配置·自定义starter·源码解析·条件注解·spring框架·java配置
小马爱打代码1 小时前
SpringBoot + Quartz + Redis:分布式任务调度系统 - 从架构设计到企业级落地
spring boot·redis·分布式
花花鱼1 小时前
android room中实体类变化以后如何迁移
android
q***87602 小时前
Spring Boot 整合 Keycloak
java·spring boot·后端
Billow_lamb2 小时前
Spring Boot2.x.x全局拦截器
java·spring boot·后端
Jomurphys2 小时前
设计模式 - 适配器模式 Adapter Pattern
android
雨白2 小时前
电子书阅读器:解析 EPUB 底层原理与实战
android·html