自定义服务单元是什么
把自研程序注册成 systemd 单元,是为了让服务获得统一的启停入口、开机自启、崩溃自动拉起和日志归集,而不用再写一堆 nohup 与自定义看护脚本。做法是在 /etc/systemd/system 下新建 <名称>.service,声明描述、启动命令、重启策略与安装目标,然后 daemon-reload 让 systemd 读到它。麒麟 V10、UOS 服务器版、openEuler 都适用,单元文件语法是 systemd 统一标准。
基本信息
| 文件位置 | /etc/systemd/system/myapp.service |
|---|---|
| 文件权限 | 644,属主 root |
| 常用 Type | simple(前台进程)、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/EXEC | ExecStart 找不到或不可执行 | 核对绝对路径、权限与解释器 |
| status=200 | ExecStart 位置写错或文件不存在 | 确认二进制路径拼写 |
| status=226/NAMESPACE | WorkingDirectory 不存在或不可访问 | 先建目录并给对属主 |
| 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 片段。