BusyBox 中文文档 下载 App

respawn 进程守护 让关键进程崩溃自动重启

为什么需要 respawn

嵌入式系统通常没有完整的进程管理框架(没有 systemd、没有 supervisord),但某些关键进程不能因为崩溃就挂掉——比如:

BusyBox init 提供了最轻量的方案:在 /etc/inittab 里用 respawn action,init 会无限循环地启动你指定的进程——进程退出后立即重新拉起。

基本用法

# /etc/inittab 里加一行
myservice::respawn:/usr/sbin/myservice --option value

这样就完成了。如果 /usr/sbin/myservice 崩溃退出,BusyBox init 会立即重新执行这条命令,把进程拉起来。没有额外的守护进程,没有配置文件复杂度。

respawn 和 once 的区别

# respawn:进程退出后自动重启(无限循环)
a::respawn:/usr/bin/daemon-a

# once:进程只跑一次,退出后不再重启
b::once:/usr/bin/daemon-b

嵌入式场景里 respawn 几乎覆盖了所有需要守护的场景,once 主要用于一次性初始化任务。

避免 respawn 风暴

如果某个进程启动后立刻崩溃(比如配置文件错了、依赖没装),BusyBox init 会疯狂重试——每秒启动几百次,浪费 CPU 和 I/O。BusyBox init 内置了风暴保护:

启动失败频率检测:BusyBox init 记录每个 respawn 进程的启动时间间隔。如果一个进程在 5 秒内连续启动超过 3 次,init 会认为它有问题,打印警告并延迟启动(每次延迟越来越长),而不是立即重试。

这个机制防止了在系统故障时 CPU 被白白烧掉,但也意味着进程一旦有 bug,修复后可能需要重启 init 才能让它立即恢复——给 init 发 HUP 信号重新加载 inittab 可以重置风暴计数器。

askfirst 的安全模式

BusyBox init 有一个独特的 action 叫 askfirst——respawn 但首次启动前会提示按回车确认:

# askfirst:首次启动前要手动按回车确认
# 后续退出/重启就不需要了,自动 respawn
shell::askfirst:/bin/sh

这个设计是为了救援模式——如果系统启动脚本跑挂了,你可以通过串口连上去,按回车进入 shell 修复配置。对于嵌入式开发阶段特别有用。

respawn vs 手动写守护脚本

很多人第一反应是自己写个 Shell 守护循环:

# 反例:别这么干
while true; do
  /usr/sbin/myservice
  sleep 1
done &

BusyBox init 的 respawn 比这种方式好太多:

对比项BusyBox respawnShell while 循环
守护者身份PID 1(init)后台 shell 进程
崩溃时的响应立即重启有 sleep 延迟
风暴保护内置需要自己写
配置方式inittab 一行额外脚本
与系统集成init 管理独立守护,关机时需要额外 kill

respawn 没有任何缺点——能就用 respawn,不要自己写守护循环。

实战示例

# /etc/inittab 中守护关键服务
# DHCP 服务——网络配置不能丢
dhcp::respawn:/usr/sbin/udhcpc -i eth0

# Web 管理界面
httpd::respawn:/usr/sbin/httpd -p 80 -h /var/www

# 串口 shell(开发调试用)
ttyS0::respawn:/sbin/getty 115200 ttyS0

# 设备主控制循环
control::respawn:/usr/local/bin/device-controller

# 日志系统
syslog::respawn:/sbin/syslogd -n
klog::respawn:/sbin/klogd -n

修改完 inittab 后给 init 发 HUP 让它重新加载:

busybox kill -HUP 1