systemd服务启动失败主因是type设置错误:type=simple误判fork退出进程为崩溃,应据进程类型选forking/exec/notify;restart策略配合restartsec可实现oom后自动恢复;路径权限、环境变量、daemon-reload缺失及workingdirectory与user组合不当亦常见。

systemd 服务文件不是写完就能跑,关键在[Unit]和[Service]段的依赖与启动逻辑是否匹配真实进程行为。
为什么 systemctl start myapp.service 报 failed,但手动运行 /opt/myapp/bin/start.sh 没问题
常见原因是 Type= 设置错误。systemd 默认按 Type=simple 处理:它认为进程一启动就“就绪”,立刻检查状态。但如果你的启动脚本是 fork 出子进程后自己退出(比如很多 Java 或 Node 后台服务),systemd 会误判为崩溃。
- 确认你的程序是前台阻塞型(如
python3 app.py)还是后台 daemon 型(如nginx -d) - 前台型 → 用
Type=simple(默认),但必须确保进程不自行 fork+exit - 后台 daemon 型 → 改用
Type=forking,并严格配好PIDFile=和ExecStart=中的启动命令(不能带&) - 不确定或想绕过 fork 判断 → 用
Type=exec(systemd 等待主进程结束才认为启动完成)或Type=notify(需程序内调用 sd_notify())
如何让服务自动拉起失败的子进程(比如 Python 进程被 OOM kill)
systemd 本身不负责“重启子进程”,它只管理你定义的 ExecStart= 所启动的那个主进程。要实现崩溃后自动恢复,得靠 Restart= 策略 + 正确的退出信号判断。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
-
Restart=on-failure:仅当进程 exit code 非 0 或被信号终止(如 SIGKILL、SIGSEGV)时重启 -
Restart=always:不管怎么退出都重启(慎用,可能掩盖配置错误) - 必须加
RestartSec=5(避免密集重启触发 systemd 的 rate limit) - 如果进程被 OOM killer 杀掉,内核发的是
SIGKILL,属于on-failure范围;但若进程自己捕获 SIGKILL 并优雅退出(不可能),则不会触发重启 - 别依赖
RestartPreventExitStatus=除非你明确知道哪些退出码代表“正常关闭”
服务启动时提示 “Unit myapp.service entered failed state” 且 journalctl -u myapp.service 显示 “Failed at step EXEC spawning…”
这基本是路径或权限问题,systemd 在 execve() 阶段就失败了,根本没跑到你的程序逻辑。
- 检查
ExecStart=路径是否绝对路径 ——ExecStart=./start.sh必败,必须写成ExecStart=/opt/myapp/start.sh - 确认该文件有执行权限:
chmod +x /opt/myapp/start.sh - 确认该文件第一行 shebang 正确(如
#!/bin/bash),且对应解释器存在 - 如果脚本里用了环境变量(如
$HOME),注意 systemd 服务默认没有用户环境 —— 改用Environment=PATH=/usr/local/bin:/usr/bin:/bin显式声明,或改用绝对路径 - 使用
systemd-analyze verify /etc/systemd/system/myapp.service可提前发现语法错误
为什么 reload 服务后配置没生效,还得 restart?
systemctl reload myapp.service 只对支持 SIGHUP 的服务有效(比如 nginx、rsyslog),而绝大多数自定义服务根本不处理这个信号。reload 不等于“重新读取 service 文件”。
- 修改了
.service文件内容(如ExecStart=、Environment=)→ 必须先systemctl daemon-reload,再systemctl restart myapp.service -
daemon-reload是告诉 systemd “重载 unit 文件”,但它不会影响已运行的服务实例 - 如果服务进程自身支持热重载(如某些 Web 服务器),那才用
reload;否则一律走 restart - 别省略
daemon-reload—— 缺了它,restart 也会沿用旧配置
真正容易被忽略的点是:systemd 对 WorkingDirectory= 和 User= 的组合极其敏感。比如设了 User=www-data 却没设 WorkingDirectory=,工作目录可能是 / 或 /root,导致相对路径配置全部失效。这类问题在 journal 里往往只显示 “Permission denied” 或 “No such file”,得结合 strace 或临时加 ExecStartPre=/bin/pwd 来定位。










