设备发到客户现场,App莫名崩溃了没人知道,等客户打电话过来,才发现设备已经"假在线"了一个星期。 重启一下能恢复,但日志没保留,问题原因永远查不到。
如果你的iMX6ULL设备跑Qt程序,这个问题迟早会遇到。本文对比我在实际项目中用过的几种保活方案,并给出最终选择。
一、要解决的问题
先明确"保活"到底要防什么,不同故障需要不同层次的方案:
| 故障类型 | 例子 | 需要的保护层次 |
|---|---|---|
| App崩溃/被误杀 | 段错误、OOM被kill、现场人员误操作 | 软件监测,自动拉起 |
| App卡死但进程还在 | 死锁、界面假死 | 软件监测(需心跳)或看门狗 |
| 系统整体假死 | 内核panic、硬件故障 | 硬件看门狗,超时复位 |
| 出问题后无法定位 | 现场没日志 | 日志循环留存 |
一个生产可用的方案,应该同时覆盖这四类。
二、方案对比
方案1:Shell轮询守护脚本
写一个脚本,每隔几秒检查一次App进程是否存活,不在了就用完整路径重新拉起来。
while true; do
pidof myapp >/dev/null 2>&1 || /home/root/myapp &
sleep 2
done
优点:零依赖、不用编译、几行代码、可读可改 缺点:脚本自身挂了没人管;只能防"进程消失",防不了卡死
方案2:systemd服务管理
编写一个 .service 文件,配置 Restart=always,让systemd守护App。
[Service]
ExecStart=/home/root/myapp
Restart=always
RestartSec=2
优点:工业标准做法,崩溃拉起稳定,有日志管理(journald) 缺点:部分裁剪过的嵌入式系统没有systemd或功能不全;依然防不了系统级假死;学习成本略高
方案3:硬件看门狗(imx6ull自带)
iMX6ULL片上有硬件看门狗,用户态程序周期性向 /dev/watchdog 写入数据即"喂狗"。一旦系统假死、程序停止喂狗,超时后(默认约60秒)硬件自动复位整个设备。
优点:唯一能防"系统级假死"的方案,硬件级,软件死了它也有效 缺点:只管复位不管拉起;有一个大坑——Magic Close(后面细说)
方案4(最终方案):守护脚本 + 看门狗 + 日志轮转,三层组合
实际项目里,单一方案都兜不住所有场景,我最终的架构是:
┌─────────────────────────────────────┐
│ 第一层:Shell守护脚本(软件层) │
│ App崩溃/退出 → 3秒内自动拉起 │
│ CPU持续过高 → 自动重启设备 │
├─────────────────────────────────────┤
│ 第二层:硬件看门狗(硬件层) │
│ 系统假死/脚本被kill → 喂狗停止 │
│ → 约60秒后硬件复位设备 │
├─────────────────────────────────────┤
│ 第三层:日志循环写入 │
│ 守护日志+App输出按大小轮转留存 │
│ 出问题有据可查 │
└─────────────────────────────────────┘
任何一层失效,下一层兜底;设备重启后由rc.local重新拉起整套,实现无人值守。
三、踩过的坑(重点)
坑1:Magic Close——看门狗"喂了等于没喂"
网上流传的喂狗写法:
echo "." > /dev/watchdog # 每次喂狗都打开再关闭设备
内核默认开启 Magic Close 特性:关闭看门狗设备时会自动解除看门狗。这意味着脚本一旦异常退出,看门狗已经被卸载,系统永远不会复位——硬件兜底彻底失效。
正确写法是打开一次、保持句柄:
exec 3> /dev/watchdog
while true; do
echo "." >&3
sleep 10
done
这个问题我排查了两天,网上的资料几乎没人提。
坑2:CPU监测单次采样误触发
Qt程序启动瞬间CPU冲高是常态,单次采样超阈值就重启设备会误伤。要改成"连续N次采样超限"才触发。
坑3:日志写满EMMC
嵌入式存储通常只有几百MB到几GB,日志只写不清理,一个月后磁盘100%满。必须按大小轮转+超期删除。
四、实测数据
- 崩溃拉起:
kill -9后约3秒内App重新运行 - CPU保护:压满全部核心后,约90秒(检测周期×连续次数)设备自动重启
- 系统假死:
kill看门狗脚本后约60秒硬件复位 - 日志:超512KB自动轮转,保留旧的一份
五、小结
| 方案 | 防App崩溃 | 防系统假死 | 上手成本 |
|---|---|---|---|
| Shell守护脚本 | ✅ | ❌ | 极低 |
| systemd | ✅ | ❌ | 中 |
| 硬件看门狗 | 间接(复位后自启) | ✅ | 低(有坑) |
| 三层组合 | ✅ | ✅ | 低 |
如果你的设备在客户现场无人值守,建议直接上三层组合。
这套方案我已经整理成完整的工程(守护脚本+看门狗+部署脚本+避坑清单,iMX6ULL实测),更新维护中,需要的话可以在我的主页看到Gitee地址(或者Gitee搜索imx6ull-daemon)。