Systemd Service 配置
Systemd Service 配置备忘录:从入门到生产级配置
技术博客 | Ubuntu 系统管理 | Systemd 服务配置
By GLM & MiniMax-M2.5
最后更新:2026-04-05
在 Linux 运维中,将程序封装为 Systemd 服务是标准操作。它不仅能实现开机自启,更重要的是提供了进程监控、日志管理和依赖控制。
本文将以一份标准配置为例,深入解析各个参数的含义与进阶用法。
1. 最小化模板 vs 生产级模板
极简模板(仅能启动)
如果你只是想临时跑一个程序,不需要自启和重启策略,只需要这几行:
1 | |
生产级模板(推荐标准)
包含了网络依赖、自动重启、安全权限和日志配置,适合部署在服务器上。
1 | |
2. [Unit] 部分:启动条件与依赖
这部分决定了服务何时启动,以及启动顺序。
- Description:服务的简短描述,systemctl status 时会显示。
- After= vs Wants=:
- After:决定顺序。After=network.target 表示网络启动后再启动本服务。
- Wants:决定依赖。Wants=network.target 表示本服务依赖网络。通常两者配合使用。
区别:如果只写 After,网络没启动好,你的服务也会启动(只是排在后面)。如果写了 Wants,网络服务启动失败,你的服务可能也会受影响(取决于依赖强度)。
- Requires=:强依赖。如果依赖的服务挂了,本服务也会被停止。
常用的启动依赖目标:- network.target:网络栈初始化完成(网卡启动)。
- network-online.target:网络真正连通(获取到 IP,能联网)。对于 FRP、Web 服务等,建议用这个。
- remote-fs.target:远程文件系统挂载完成(如 NFS)。
3. [Service] 部分:核心行为配置
3.1 进程类型 (Type)
- simple (最常用):默认值。认为 ExecStart 启动的进程就是主进程。服务启动后,systemd 认为服务已就绪。
- forking:经典 Unix 风格。ExecStart 会 fork 一个子进程后退出,父进程退出代表启动成功(如 Nginx 默认行为)。
- notify:服务启动完成后,会主动向 systemd 发送信号。适合需要确信服务完全准备好才接收流量的场景。
3.2 自动重启策略 (Restart)
这是保证服务高可用的关键。
配合参数:
- Restart=on-failure:如果服务退出非 0 状态,会自动重启。
- Restart=always:如果服务退出非 0 状态,会自动重启。
- Restart=on-abort:如果服务退出非 0 状态,会自动重启。
- RestartSec=5s:重启前等待 5 秒,防止疯狂重启炸毁服务器。
- StartLimitIntervalSec=60s 和 StartLimitBurst=3:与 RestartSec=5s 一起使用,防止服务持续重启,导致系统资源耗尽。
- StartLimitIntervalSec=60s:60 秒内重启超过 3 次,则不再尝试重启,进入 failed 状态。
3.3 日志输出详解
Systemd 通过捕获标准输出来管理日志,不需要你在程序里自己写日志文件路径。
- StandardOutput=:定义标准输出的去向。
- StandardError=:定义标准错误的去向。
常用配置值: - journal (推荐):
输出到 Systemd Journal。
优点:自动轮转,不会撑爆磁盘;支持 journalctl -u 服务名 快速查看;自动记录时间戳。
自动获取 stdout 吗?:是的,程序里 print() 或 console.log() 输出的内容会被 systemd 捕获并写入 journal。 - syslog:
转发给系统 syslog 守护进程(如 rsyslog),可进一步配置转发到远程日志服务器。 - file:/path/to/log.log:
直接写入文件。
缺点:需要自己处理日志轮转,文件权限问题容易出错。一般不推荐,除非有特殊需求。 - append:/path/to/log.log:
同上,但是以追加模式写入(不会覆盖旧文件)。
如何查看日志?
1 | |
4. [Install] 部分:随系统启动的原理
这部分只有在执行 systemctl enable 时才会被读取。
4.1 WantedBy=multi-user.target 是什么?
Target 概念:Systemd 用 “Target” 代替了传统的运行级别。
- poweroff.target: 关机状态。
- rescue.target: 单用户救援模式。
- multi-user.target: 多用户命令行模式(对应旧版 Runlevel 3)。这是服务器的标准运行状态。
- graphical.target: 图形界面模式(依赖 multi-user.target)。
4.2 为什么随系统启动?
当你执行 systemctl enable my-service 时,Systemd 会根据 [Install] 里的配置,在 /etc/systemd/system/multi-user.target.wants/ 目录下创建一个软链接,指向你的服务文件。
系统启动时,Systemd 会启动 multi-user.target,而 multi-user.target “想要” 所有在那个目录下的服务,于是就把你的服务拉起来了。
4.3 其他 [Install] 常用选项
- RequiredBy=target:
与 WantedBy 类似,但这是强依赖。
区别:如果服务启动失败,WantedBy 不会报错继续启动系统;RequiredBy 会导致系统启动流程报错或进入紧急模式。 - Alias=servicename:
给服务起别名。比如 systemctl enable servicename 也可以用别名来操作。 - Also=another.service:
联动操作。当你 enable 这个服务时,也会自动 enable 另一个服务。
5. 进阶配置:还能加什么?
5.1 环境变量
程序往往需要数据库密码或 API Key,不要写在命令行里。
1 | |
5.2 执行前置与后置
ExecStartPre=:在主进程启动前执行的命令。常用于检查配置文件、创建临时目录。
ExecStartPost=:启动后执行的命令。
ExecStopPost=:停止后执行的命令(无论是否正常停止)。常用于清理残留文件。
示例:启动前检查目录
1 | |
5.3 资源限制
防止程序内存泄漏拖垮系统。
1 | |
5.4 安全加固
如果服务暴露在公网,建议开启安全隔离:
1 | |
6. 服务管理常用命令
保存配置后,需要执行以下命令使服务正常运行:
1 | |
其他常用日志命令
1 | |
常见问题排查
1 | |
总结
一个健壮的服务配置应包含:
- 网络依赖 (
After=network-online.target) - 故障自愈 (
Restart=on-failure) - 日志管理 (
StandardOutput=journal) - 权限最小化 (
User=non-root)
保存配置后,记得执行以下命令使其生效:
1 | |