CentOS下systemctl启动Python FastAPI服务报203/EXEC错误
问题定位
状态码203/EXEC是systemd抛出的进程执行失败错误,代表systemd未能成功运行ExecStart配置的启动命令,和应用本身代码逻辑无关——手动执行命令可正常启动已经印证了这一点,核心问题出在systemd服务配置错误,按影响优先级排序:
- 服务类型配置错误:配置中
Type=forking适配的是启动后会自行fork后台进程、父进程立刻退出的传统daemon程序,但直接调用python运行uvicorn时,uvicorn默认是前台驻留运行、不会主动fork后台进程,systemd无法匹配forking类型的启动流程判定逻辑,直接判定执行失败。 - target配置拼写错误:
WantedBy=multiuser.target为错误写法,systemd标准运行级target名为multi-user.target,缺失中间的连字符会导致开机自启配置失效。 - 缺失工作目录配置:未指定
WorkingDirectory时,systemd会以根目录/作为服务运行的工作目录,若应用内使用相对路径加载模型、配置文件,会出现文件找不到的错误。 - 无重启间隔配置:服务启动失败后会立刻无限重试,短时间内触发systemd的启动频率限制,直接标记服务为failed状态。
排查修复步骤
- 先重置服务失败计数,解除启动锁定:
sudo systemctl reset-failed ml.service
- 修改
/usr/lib/systemd/system/ml.service配置为以下正确内容:
[Unit] Description=Ml api After=network.target [Service] User=root WorkingDirectory=/home/a.nikitin@corp.bsv.legal/bsv_ml_api/ ExecStart=/usr/local/bin/python3.9 -u /home/a.nikitin@corp.bsv.legal/bsv_ml_api/app.py Restart=on-failure RestartSec=3 Type=simple [Install] WantedBy=multi-user.target
配置修正说明:
- 将
Type从forking改为simple,适配uvicorn前台运行的模式,这是最核心的修复点 - 修正
multi-user.target的拼写错误 - 增加
WorkingDirectory配置,指定服务运行根目录,避免相对路径加载资源失败 - 增加
RestartSec=3配置,设置失败后3秒再重启,避免短时间重试触发启动频率限制 - 删除冗余的
ExecStop配置:simple类型的服务由systemd直接管理主进程生命周期,停止服务时会自动发送SIGTERM信号,无需手动编写kill命令 - 增加
After=network.target配置,保证服务在网络就绪后再启动,避免初始化时网络相关逻辑报错
- 重载systemd配置使修改生效,再启动服务:
sudo systemctl daemon-reload sudo systemctl start ml.service
- 查看服务状态确认启动正常:
sudo systemctl status ml.service
仍报错的补充排查点
如果按上述配置修改后仍报203/EXEC错误,按以下顺序排查:
- 检查python解释器权限:执行
ls -l /usr/local/bin/python3.9,确认文件有可执行权限(权限位包含x),无权限则执行sudo chmod +x /usr/local/bin/python3.9赋权 - 检查SELinux拦截:CentOS默认开启SELinux,会阻止systemd执行用户家目录下的程序,临时执行
sudo setenforce 0关闭SELinux测试,如果服务可正常启动,要么将代码迁移到/opt/、/srv/等标准服务部署目录,要么配置SELinux规则放行对应路径的执行权限 - 检查uvicorn启动参数:如果app.py内的
uvicorn.run()配置了daemon=True,请删除该参数,systemd管理的服务必须以前台模式运行,禁止自行fork后台进程 - 检查用户权限:如果python依赖是安装在
a.nikitin@corp.bsv.legal普通用户下而非全局,将配置中User=root改为对应用户名,避免root用户找不到已安装的python依赖包
内容的提问来源于stack exchange,提问作者Alex Nikitin
相关产品推荐
相关产品推荐

