首页/系统/信创系统运维速查/编写自定义 systemd 服务单元
服务与运维65 条

编写自定义 systemd 服务单元

把自研程序注册成受管服务:在 /etc/systemd/system 写 .service 文件,声明 ExecStart、Restart 与安装段,daemon-reload 后 enable --now 纳入开机与守护管理。

信创系统运维速查系统更新于 2026-10-13

自定义服务单元是什么

把自研程序注册成 systemd 单元,是为了让服务获得统一的启停入口、开机自启、崩溃自动拉起和日志归集,而不用再写一堆 nohup 与自定义看护脚本。做法是在 /etc/systemd/system 下新建 <名称>.service,声明描述、启动命令、重启策略与安装目标,然后 daemon-reload 让 systemd 读到它。麒麟 V10、UOS 服务器版、openEuler 都适用,单元文件语法是 systemd 统一标准。

基本信息

文件位置/etc/systemd/system/myapp.service
文件权限644,属主 root
常用 Typesimple(前台进程)、forking(自行后台化)、oneshot(一次性)
生效方式systemctl daemon-reload 后 enable --now
日志去向标准输出与标准错误自动进 journald,用 journalctl -u 查看

示例单元文件

示例单元文件
[Unit]
Description=MyApp Service                       # 描述,status 里显示
After=network-online.target                    # 等网络就绪后再启动
Wants=network-online.target                    # 弱依赖,缺失也不阻止启动

[Service]
Type=simple                                     # 程序在前台运行
User=appuser                                    # 以专用账号运行,不要用 root
WorkingDirectory=/opt/myapp                     # 工作目录必须是已存在的绝对路径
ExecStart=/opt/myapp/bin/myapp -c /etc/myapp/app.conf   # 必须是绝对路径
Restart=on-failure                              # 异常退出自动重拉
RestartSec=5                                    # 重拉间隔,避免疯狂重启
LimitNOFILE=65535                               # 连接数大的服务要放开
EnvironmentFile=-/etc/myapp/app.env             # 环境变量文件,前缀 - 表示可缺失

[Install]
WantedBy=multi-user.target                      # enable 时挂进多用户启动目标

上线与校验

上线与校验
systemctl daemon-reload                      # 改完单元文件必须执行
systemctl enable --now myapp.service         # 设自启并立即启动
systemctl status myapp.service --no-pager -l  # 看状态,-l 显示完整命令
journalctl -u myapp -n 100 --no-pager         # 启动失败看这里
systemctl show myapp -p Restart,User,ExecStart  # 确认实际生效的字段

常见失败与含义

状态提示含义处理方向
status=203/EXECExecStart 找不到或不可执行核对绝对路径、权限与解释器
status=200ExecStart 位置写错或文件不存在确认二进制路径拼写
status=226/NAMESPACEWorkingDirectory 不存在或不可访问先建目录并给对属主
activating(auto-restart)在反复重启看 journalctl 里程序自身的报错
ExecStart 必须写绝对路径,systemd 不解析 PATH 与 shell 通配;需要 shell 语法(管道、重定向、变量展开)时必须显式写成 /bin/bash -c "..."。自研程序若自己 fork 到后台,用 Type=forking 并配置 PIDFile,否则 systemd 会误判进程退出。
改单元文件只 restart 不 daemon-reload,systemd 仍按旧定义运行,表现为改了没反应。想让自定义参数临时覆盖而非改原文件,可在 /etc/systemd/system/<名称>.service.d/ 下放 dropin 片段。

易错点

  • 改完单元文件忘记 daemon-reload,直接 restart 却还是旧行为,排查方向会被带偏
  • WorkingDirectory 与日志目录没提前创建或属主不对,首次启动即失败,报 200/203/226 类状态码
  • 用 root 直接跑业务进程,一旦程序被利用影响面扩到整机,应建专用账号并限制权限
  • Type 选错:程序自己后台化却写 simple,systemd 认为进程已退出,于是反复重启直到触发启动频率限制

数据来源与参考

  • man 5 systemd.service
  • openEuler 文档:编写 systemd 单元文件
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌