linux下OTA升级方案

在Linux下实现应用程序的OTA(空中升级)升级,并确保升级失败后能自动回退到旧版本,保证系统不宕机,可通过以下方案实现:


核心方案:双版本共存 + 原子切换 + 回滚机制

1. 文件系统布局

bash

复制

下载

/app
├── versions
│   ├── v1.0.0       # 旧版本(当前运行)
│   │   └── bin
│   │       └── myapp
│   └── v1.1.0       # 新版本(待升级)
│       └── bin
│           └── myapp
├── current -> /app/versions/v1.0.0  # 符号链接指向当前版本
└── update.sh         # 升级脚本
2. 升级流程
  1. 下载新版本
    将新版本解压到独立目录(如/app/versions/v1.1.0),不影响当前运行版本。

  2. 预验证新版本(关键步骤)
    在切换前检查新版本完整性:

    bash

    # 示例:检查文件哈希、执行测试用例
    sha256sum -c /app/versions/v1.1.0/checksum.txt
    /app/versions/v1.1.0/bin/myapp --self-test
  3. 原子切换版本
    使用符号链接的原子操作切换版本:

    bash

    ln -sfn /app/versions/v1.1.0 /app/current.tmp && mv -Tf /app/current.tmp /app/current
  4. 重启应用程序
    通过进程管理器(如systemd)重启应用:

    bash

    systemctl restart myapp

3. 失败回滚机制

方案一:进程管理器自动回退

使用 systemd 的 Restart= 和 StartLimitBurst= 策略:

ini

# /etc/systemd/system/myapp.service
[Service]
ExecStart=/app/current/bin/myapp
Restart=on-failure         # 失败时重启
RestartSec=5s              # 等待5秒后重启
StartLimitInterval=60s     # 60秒内最多尝试3次
StartLimitBurst=3

# 若连续失败,触发回滚脚本
ExecStartPost=/bin/sh -c 'if [ $EXIT_STATUS != 0 ] && [ $(systemctl show -p NRestarts myapp.service | cut -d= -f2) -ge 3 ]; then /app/rollback.sh; fi'
方案二:独立看门狗进程

编写看门狗脚本 (/app/watchdog.sh):

bash

#!/bin/bash
while true; do
    # 启动应用并记录PID
    /app/current/bin/myapp &
    APP_PID=$!
    wait $APP_PID
    EXIT_CODE=$?
    
    # 检测是否异常退出(非主动退出)
    if [ $EXIT_CODE -ne 0 ] && [ $EXIT_CODE -ne 130 ]; then  # 130=Ctrl+C
        echo "App crashed! Attempting rollback..."
        /app/rollback.sh
    fi
    sleep 5
done
回滚脚本 (/app/rollback.sh)

bash

复制

下载

#!/bin/bash
# 切换回上一个可用版本(如v1.0.0)
ln -sfn /app/versions/v1.0.0 /app/current
systemctl restart myapp  # 或看门狗自动重启

4. 增强安全性设计

  • 版本保留策略
    保留至少一个旧版本,升级成功后清理历史版本。

  • 断电保护
    使用 fsync() 或 sync 确保写操作落盘,避免断电导致符号链接损坏。

  • 备份用户数据
    升级前备份配置文件(如 cp -a /etc/myapp /backup)。

  • 灰度发布
    先升级少量设备,验证成功后再全量推送。


5. 完整升级流程示例

bash

复制

下载

#!/bin/bash
# /app/update.sh

NEW_VERSION="v1.1.0"
DOWNLOAD_URL="http://example.com/myapp-$NEW_VERSION.tar.gz"

# 1. 下载并解压新版本
mkdir -p "/app/versions/$NEW_VERSION"
curl -sL "$DOWNLOAD_URL" | tar -xz -C "/app/versions/$NEW_VERSION"

# 2. 预验证
if ! sha256sum -c "/app/versions/$NEW_VERSION/checksum.txt"; then
    echo "Checksum failed! Aborting."
    rm -rf "/app/versions/$NEW_VERSION"
    exit 1
fi

# 3. 原子切换
ln -sfn "/app/versions/$NEW_VERSION" /app/current.tmp
mv -Tf /app/current.tmp /app/current

# 4. 重启应用
systemctl restart myapp

# 5. 验证新版本(可选)
if ! curl -s http://localhost:8080/health; then
    echo "New version failed! Rolling back."
    /app/rollback.sh
fi

关键点总结

机制实现方式作用
版本隔离每个版本独立目录新旧版本互不干扰
原子切换ln -sfn + mv -Tf避免切换中途失败
自动回滚systemd失败重启策略或看门狗脚本崩溃时退回旧版本
安全更新预校验哈希、灰度发布防止损坏版本被激活

注意:对于关键系统(如嵌入式设备),推荐结合 双系统分区(A/B更新) 方案(如Android OTA),由Bootloader决定启动分区,彻底避免软故障。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值