Linux systemd 服务部署与守护进程管理指南
wxk1991 Lv5

Linux systemd 服务部署与守护进程管理指南

很多后端服务最终都会以一个长期运行的进程部署在 Linux 服务器上。直接用 nohupscreen 虽然能跑起来,但在自动重启、日志管理、开机启动、优雅停止这些方面都不够规范。

systemd 是现代 Linux 发行版里最常用的服务管理系统。本文用一个实际后端服务为例,讲清楚如何编写 service 文件、管理服务生命周期、查看日志,以及处理常见问题。


一、准备服务目录

假设我们要部署的程序叫 myapp,推荐把它放在固定目录:

1
2
3
sudo mkdir -p /opt/myapp
sudo mkdir -p /etc/myapp
sudo mkdir -p /var/log/myapp

常见目录职责:

1
2
3
/opt/myapp      放二进制文件、静态资源、启动脚本
/etc/myapp 放配置文件
/var/log/myapp 放应用自己的日志文件

如果你的程序直接输出到 stdout,日志可以完全交给 journald,不一定要写入 /var/log/myapp


二、创建运行用户

不要用 root 直接运行业务服务。可以单独创建系统用户:

1
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp

然后设置目录权限:

1
2
sudo chown -R myapp:myapp /opt/myapp
sudo chown -R myapp:myapp /var/log/myapp

配置目录通常可以 root 拥有,服务用户只读:

1
2
sudo chown -R root:root /etc/myapp
sudo chmod -R 755 /etc/myapp

这样即使服务被攻击,攻击者也不会天然拥有 root 权限。


三、编写 service 文件

创建文件:

1
sudo vim /etc/systemd/system/myapp.service

示例内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Unit]
Description=MyApp Backend Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp --config /etc/myapp/config.yaml
Restart=on-failure
RestartSec=5
Environment=APP_ENV=production
Environment=TZ=Asia/Shanghai

NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

几个关键字段:

  • After=network-online.target:等网络就绪后再启动
  • UserGroup:指定低权限用户运行
  • WorkingDirectory:指定工作目录
  • ExecStart:真正的启动命令
  • Restart=on-failure:异常退出自动重启
  • RestartSec=5:失败后等待 5 秒再拉起
  • WantedBy=multi-user.target:允许配置开机启动

四、加载并启动服务

每次新增或修改 service 文件后,都要执行:

1
sudo systemctl daemon-reload

启动服务:

1
sudo systemctl start myapp

查看状态:

1
sudo systemctl status myapp

设置开机自启:

1
sudo systemctl enable myapp

如果要立即启用并启动,可以用:

1
sudo systemctl enable --now myapp

五、查看日志

systemd 默认会收集 stdout 和 stderr。查看服务日志:

1
sudo journalctl -u myapp

实时查看:

1
sudo journalctl -u myapp -f

查看最近 100 行:

1
sudo journalctl -u myapp -n 100

按时间筛选:

1
sudo journalctl -u myapp --since "2026-06-04 20:00:00"

如果服务启动失败,journalctl 通常比 systemctl status 给出的信息更完整。


六、更新服务版本

常见发布流程:

1
2
3
4
5
sudo systemctl stop myapp
sudo cp myapp /opt/myapp/myapp
sudo chown myapp:myapp /opt/myapp/myapp
sudo chmod +x /opt/myapp/myapp
sudo systemctl start myapp

如果服务支持优雅关闭,也可以直接 restart:

1
sudo systemctl restart myapp

发布后检查:

1
2
sudo systemctl status myapp
sudo journalctl -u myapp -n 50

不要只看进程是否存在,还要确认日志中没有配置错误、数据库连接错误或端口监听失败。


七、常见问题排查

1. 修改 service 后不生效

通常是忘了执行:

1
sudo systemctl daemon-reload

systemd 不会自动重新读取 service 文件。

2. 服务没有权限读配置

检查运行用户:

1
ps aux | grep myapp

检查文件权限:

1
ls -l /etc/myapp/config.yaml

如果配置文件只允许 root 读取,而服务使用 myapp 用户运行,就会启动失败。

3. 端口被占用

1
sudo ss -lntp | grep 8080

找到占用端口的进程后,再决定是修改端口还是停止旧进程。

4. 服务频繁重启

查看重启次数:

1
systemctl status myapp

查看具体错误:

1
journalctl -u myapp -n 200

如果程序启动后立刻退出,通常是配置缺失、依赖不可达、端口冲突或执行文件没有权限。


八、生产建议

生产环境建议至少做到:

  • 使用独立低权限用户运行服务
  • service 文件纳入版本管理或部署脚本管理
  • 所有配置文件路径写成绝对路径
  • 设置合理的重启策略
  • 应用日志输出到 stdout 或统一日志目录
  • 发布后检查状态和最近日志

systemd 的价值不只是“让进程后台运行”,而是把进程生命周期标准化。服务越多,这种标准化越重要。