Linux systemd 从入门到实战:Unit、systemctl、Service 与日志排障

前言

在现代 Linux 发行版中,systemd 几乎已经成为绕不开的基础组件。我们平时执行的:

1
2
3
4
systemctl start nginx
systemctl enable nginx
systemctl status nginx
journalctl -u nginx

背后都属于 systemd 的服务管理体系。

如果只把 systemd 理解成“用来启动服务的工具”,其实低估了它。systemd 不仅承担 Linux 启动阶段的初始化工作,还负责服务生命周期管理、依赖关系编排、日志、定时任务、挂载点、Socket 激活、用户会话以及部分系统配置管理。

本文结合几篇 systemd 资料重新整理,并对重复内容进行了合并。重点不是罗列所有配置项,而是建立一套真正能用于 Linux 服务器管理、服务部署和故障排查的知识体系。

一、systemd 到底是什么

Linux 内核启动完成以后,需要有一个用户空间进程负责继续初始化系统,例如挂载文件系统、启动网络、启动 SSH、数据库、Web 服务等。

这个特殊进程通常就是 PID 1

在传统 Linux 中,PID 1 常由 SysV init、Upstart 等系统承担;现代主流发行版则基本采用 systemd。

可以通过下面的命令确认 PID 1:

1
ps -p 1 -o pid,comm,args

常见输出:

1
2
PID COMMAND         COMMAND
1 systemd /sbin/init

很多发行版中的 /sbin/init 实际上最终会指向 systemd。

1.1 systemd 相比传统 SysV init 的主要变化

传统 SysV init 大量依赖 /etc/init.d/ 下的 Shell 脚本,并通过 runlevel 控制不同启动模式。它的问题之一是服务之间的依赖关系不够结构化,启动过程也更偏向顺序执行。

systemd 则把系统中的服务和资源统一抽象为 Unit,并明确描述依赖关系和启动顺序。因此,在依赖条件允许时,多个服务可以并行启动。

systemd 的几个核心特点包括:

  • 以 Unit 为统一管理模型;
  • 支持服务依赖关系和启动顺序编排;
  • 支持并行启动;
  • 支持 Socket、D-Bus、Path 等按需激活机制;
  • 使用 cgroup 跟踪和管理服务进程;
  • 统一提供 systemctl 管理接口;
  • 通过 systemd-journald 和 journalctl 管理日志;
  • 可以使用 Timer Unit 替代部分 cron 场景;
  • 可以分析系统启动耗时和依赖链。

所以,与其把 systemd 理解成一个“新版 init”,不如把它理解成 Linux 上的一套 系统与服务管理框架


二、理解 systemd 的关键:Unit

systemd 管理的基本对象叫做 Unit(单元)

系统服务、Socket、挂载点、设备、定时器、目标状态等,都可以被表示成不同类型的 Unit。

常见 Unit 类型如下:

Unit 类型 后缀 作用
Service .service 管理后台服务和守护进程
Socket .socket 管理 Socket,可用于按需激活服务
Target .target 对多个 Unit 进行逻辑分组
Device .device 表示内核识别到的设备
Mount .mount 管理文件系统挂载点
Automount .automount 管理自动挂载
Swap .swap 管理 Swap 设备或文件
Timer .timer 定时触发任务
Path .path 监控文件或目录变化并触发 Unit
Slice .slice 对进程进行资源层级分组
Scope .scope 管理由 systemd 外部创建的进程组

不同 systemd 版本的 Unit 类型和细节可能存在差异,因此生产环境中应以当前系统的 man page 为准。

可以查看已经加载的 Unit:

1
systemctl list-units

查看所有 Service Unit:

1
systemctl list-units --type=service

包括当前未激活的 Unit:

1
systemctl list-units --type=service --all

查看系统已经安装的 Unit 文件:

1
systemctl list-unit-files

这两个命令很容易混淆:

  • list-units 更关注当前 systemd 已加载到内存中的 Unit;
  • list-unit-files 更关注磁盘上安装的 Unit 文件以及 enable 状态。

三、Unit 文件放在哪里

管理员最常接触的 systemd Unit 文件目录主要有:

1
2
3
/etc/systemd/system/
/run/systemd/system/
/usr/lib/systemd/system/

部分 Debian/Ubuntu 系统中也经常看到:

1
/lib/systemd/system/

实际目录布局可能因发行版不同而略有差异。

从运维角度,可以简单记住:

1
2
3
/etc/systemd/system/      管理员自己的配置和覆盖配置
/run/systemd/system/ 运行期间动态产生的配置,重启后通常消失
/usr/lib/systemd/system/ 软件包或发行版提供的默认 Unit

通常 /etc/systemd/system/ 的优先级高于发行版提供的默认 Unit。

3.1 不建议直接修改 /usr/lib/systemd/system/

例如 Nginx、Docker、PostgreSQL 或 SSH 等通过软件包安装以后,其 Service 文件通常由 RPM/DEB 软件包管理。

如果直接修改:

1
/usr/lib/systemd/system/xxx.service

软件升级时可能被覆盖。

更推荐:

1
systemctl edit xxx.service

它会创建类似:

1
/etc/systemd/system/xxx.service.d/override.conf

的 Drop-in 配置。

查看一个服务最终由哪些配置组成:

1
systemctl cat xxx.service

这在排查“我明明改了配置,为什么实际行为不一样”时非常有用。


四、systemctl:systemd 最常用的管理工具

systemctl 是管理 systemd 的核心命令。

4.1 启动、停止和重启服务

启动:

1
sudo systemctl start nginx.service

停止:

1
sudo systemctl stop nginx.service

重启:

1
sudo systemctl restart nginx.service

重新加载服务自身的配置:

1
sudo systemctl reload nginx.service

如果支持 reload 就 reload,否则 restart:

1
sudo systemctl reload-or-restart nginx.service

.service 后缀在很多场景可以省略:

1
systemctl restart nginx

4.2 查看服务状态

1
systemctl status nginx

判断当前是否运行:

1
systemctl is-active nginx

判断是否设置为开机启动:

1
systemctl is-enabled nginx

查看详细属性:

1
systemctl show nginx

例如只查询主进程 PID:

1
systemctl show nginx -p MainPID

4.3 start 和 enable 不是一回事

这是 systemd 初学者最常踩的坑之一。

执行:

1
systemctl start nginx

表示:

现在启动 nginx。

但它不意味着下一次开机时一定自动启动。

执行:

1
systemctl enable nginx

表示:

建立相应的启动依赖关系,使 nginx 在目标 Target 激活时自动启动。

但 enable 默认不代表“现在立即启动”。

如果希望同时完成:

1
sudo systemctl enable --now nginx

相反,如果希望停止并取消自启动:

1
sudo systemctl disable --now nginx

4.4 mask 比 disable 更彻底

禁用开机启动:

1
systemctl disable nginx

并不代表 nginx 无法被手动启动,也不代表它不能作为其他 Unit 的依赖被拉起。

如果希望彻底阻止某个 Unit 启动,可以:

1
sudo systemctl mask nginx

取消屏蔽:

1
sudo systemctl unmask nginx

因此可以简单理解为:

1
2
disable = 不自动启动
mask = 不允许启动

五、Unit 的状态:enabled、disabled、static、masked

执行:

1
systemctl list-unit-files

经常会看到下面几种状态。

enabled

已经建立启动依赖,通常意味着会随某个 Target 自动启动。

disabled

Unit 文件存在,但没有设置为自动启动。

static

这个 Unit 通常没有可用于 enable[Install] 配置,主要作为其他 Unit 的依赖被拉起。

static 不代表这个服务“坏了”,也不代表它不能运行。

masked

Unit 被屏蔽,systemd 会拒绝启动它。

排查一个服务为什么无法启动时,可以先检查:

1
systemctl is-enabled xxx.service

如果看到:

1
masked

那就先别继续和配置文件搏斗了——systemd 已经在门口把它拦下来了。


六、Target:systemd 如何组织系统状态

传统 SysV init 使用 runlevel 表示不同系统运行级别。

systemd 使用 Target Unit 表示某一组 Unit 的逻辑集合。

常见 Target:

Target 含义
multi-user.target 多用户命令行环境
graphical.target 图形界面环境
rescue.target 救援模式
emergency.target 更精简的紧急模式
reboot.target 重启
poweroff.target 关机
default.target 默认启动目标

查看当前默认 Target:

1
systemctl get-default

例如服务器通常可以设置为:

1
sudo systemctl set-default multi-user.target

桌面环境可以使用:

1
sudo systemctl set-default graphical.target

临时切换 Target:

1
sudo systemctl isolate multi-user.target

注意:isolate 不只是“进入某个 Target”,它还可能停止不属于目标依赖关系的其他 Unit,因此在生产服务器上执行前要确认影响范围。


七、systemd 最重要的概念之一:依赖和顺序是两回事

在 Unit 文件里经常会看到:

1
2
Requires=postgresql.service
After=postgresql.service

很多人第一次看到会认为这两个配置意思差不多,其实完全不是一个维度。

7.1 Requires 和 Wants:描述依赖关系

强依赖:

1
Requires=postgresql.service

表示当前 Unit 依赖 PostgreSQL。

弱依赖:

1
Wants=postgresql.service

表示希望 PostgreSQL 一起启动,但 PostgreSQL 启动失败不一定导致当前 Unit 整体失败。

一般情况下,如果不是严格的生死依赖关系,Wants= 往往更宽松。

7.2 After 和 Before:描述启动顺序

1
After=postgresql.service

表示:

当两个 Unit 都需要启动时,当前 Unit 应该排在 PostgreSQL 之后。

但是 After= 本身不会主动把 PostgreSQL 拉起来。

反过来:

1
Before=xxx.service

表示当前 Unit 排在 xxx 之前启动。

所以:

1
After=network.target

不是“依赖 network.target”的同义词。

可以把它们记成:

1
2
Wants / Requires = 要不要一起参与
After / Before = 谁先谁后

真实的服务通常会把二者组合使用。

例如:

1
2
3
[Unit]
Wants=network-online.target
After=network-online.target

八、Service Unit 文件结构

一个典型的 .service 文件通常包含三个部分:

1
2
3
4
5
6
7
8
[Unit]
...

[Service]
...

[Install]
...

8.1 [Unit]

主要描述:

  • Unit 是什么;
  • 与其他 Unit 有什么依赖;
  • 启动顺序如何安排。

例如:

1
2
3
[Unit]
Description=My Application
After=network.target

常见配置:

1
2
3
4
5
6
7
Description=
Documentation=
Wants=
Requires=
After=
Before=
Conflicts=

8.2 [Service]

主要描述服务进程如何启动、停止、重启以及使用什么运行环境。

常见配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Type=
User=
Group=
WorkingDirectory=
Environment=
EnvironmentFile=
ExecStart=
ExecStartPre=
ExecStartPost=
ExecReload=
ExecStop=
Restart=
RestartSec=
TimeoutStartSec=
TimeoutStopSec=

8.3 [Install]

主要在执行:

1
2
systemctl enable
systemctl disable

时使用。

常见配置:

1
2
[Install]
WantedBy=multi-user.target

它的含义可以理解为:

enable 当前服务时,把它挂到 multi-user.target 的启动依赖关系中。


九、Service 的 Type 怎么选

常见 Service 类型包括:

simple

最常见的长时间运行程序之一。

1
2
Type=simple
ExecStart=/opt/myapp/myapp

systemd 直接把 ExecStart 启动的进程作为主要服务进程进行管理。

forking

适用于传统 Unix daemon:父进程启动后 fork 子进程,然后父进程退出。

1
Type=forking

很多历史服务使用这种模式,但现代应用如果本身支持前台运行,通常没有必要为了“后台化”再 fork 一次。

oneshot

适合执行一次任务然后退出,例如初始化脚本:

1
2
Type=oneshot
ExecStart=/usr/local/bin/init-data.sh

notify

服务在真正准备就绪后主动通知 systemd。

这需要应用本身支持 systemd notification 机制。

dbus

用于依赖 D-Bus 名称注册完成来判断服务就绪的程序。

对于普通自研 Java、Go、Python、Node.js 后台应用,最常见的原则是:

应用直接以前台进程方式运行,让 systemd 自己负责“后台管理”,不要在应用启动脚本里再套 nohup ... &


十、实战:把一个 Java 应用交给 systemd 管理

假设应用结构为:

1
2
3
/opt/demo/
├── demo.jar
└── application.env

创建专用用户:

1
2
sudo useradd --system --no-create-home --shell /sbin/nologin demo
sudo chown -R demo:demo /opt/demo

创建:

1
/etc/systemd/system/demo.service

内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=Demo Java Application
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=demo
Group=demo
WorkingDirectory=/opt/demo
EnvironmentFile=-/opt/demo/application.env
ExecStart=/usr/bin/java -Xms512m -Xmx512m -jar /opt/demo/demo.jar
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

然后执行:

1
2
sudo systemctl daemon-reload
sudo systemctl enable --now demo.service

查看状态:

1
systemctl status demo.service

实时查看日志:

1
journalctl -u demo.service -f

重启:

1
sudo systemctl restart demo.service

10.1 为什么不要写成 nohup

不建议这样:

1
ExecStart=/bin/bash -c 'nohup java -jar demo.jar > demo.log 2>&1 &'

原因是 systemd 本身就是服务管理器。

如果再次人为后台化,反而会让主进程识别、退出状态、重启策略、日志和生命周期控制变复杂。

正确思路是:

1
2
3
4
5
应用保持前台运行

systemd 负责后台守护

journald 负责收集标准输出和标准错误

十一、修改 Unit 后为什么一定要 daemon-reload

修改:

1
/etc/systemd/system/demo.service

以后,只执行:

1
systemctl restart demo

不一定会让 systemd 重新读取 Unit 文件定义。

应该先执行:

1
sudo systemctl daemon-reload

然后:

1
sudo systemctl restart demo

可以记成:

1
2
改应用配置        -> 通常重启/Reload 应用
改 systemd Unit -> daemon-reload + restart

还可以先验证 Unit 文件:

1
systemd-analyze verify /etc/systemd/system/demo.service

这对发现拼写错误和部分配置问题很有帮助。


十二、ExecStart 不是 Shell 命令行

另一个常见坑:

1
ExecStart=/opt/demo/start.sh > /var/log/demo.log 2>&1

很多人以为 systemd 会像 Bash 一样解释 >2>&1|&& 等符号。

实际上,ExecStart= 默认并不是把整行交给 Shell 解释。

因此下面这种复杂 Shell 逻辑不要直接塞进去:

1
ExecStart=command1 && command2 | command3 > file

如果确实依赖 Shell,可以显式写:

1
ExecStart=/bin/bash -c 'command1 && command2'

但更好的方式通常是把复杂逻辑独立到脚本中:

1
ExecStart=/opt/demo/bin/start.sh

让 Unit 文件保持简单、可读、可维护。


十三、Restart:让 systemd 正确守护服务

一个非常实用的配置是:

1
2
Restart=on-failure
RestartSec=5s

它表示进程异常退出后等待 5 秒再重启。

常见 Restart 策略包括:

1
2
3
4
5
6
7
no
on-success
on-failure
on-abnormal
on-abort
on-watchdog
always

普通服务通常优先考虑:

1
Restart=on-failure

而不是无脑:

1
Restart=always

因为“无论为什么退出都拉起来”有时会掩盖正常退出、配置错误或部署过程中的实际意图。

如果程序因为配置错误瞬间退出,还可能形成:

1
启动 -> 失败 -> 重启 -> 失败 -> 重启……

这时候应该结合:

1
2
systemctl status xxx
journalctl -u xxx

先找根因,而不是和 systemd 比谁更执着。


十四、journalctl:systemd 体系中的日志查看工具

systemd-journald 会收集大量系统和服务日志,journalctl 用于查询这些日志。

14.1 查看全部日志

1
journalctl

14.2 查看当前启动周期

1
journalctl -b

查看上一次启动:

1
journalctl -b -1

查看启动历史:

1
journalctl --list-boots

14.3 查看指定服务

1
journalctl -u nginx.service

只看最后 100 行:

1
journalctl -u nginx.service -n 100

持续追踪:

1
journalctl -u nginx.service -f

这基本就是 systemd 环境中的:

1
tail -f

14.4 按时间过滤

1
journalctl --since today
1
journalctl --since "2026-08-13 10:00:00"
1
2
3
journalctl \
--since "2026-08-13 10:00:00" \
--until "2026-08-13 11:00:00"

配合服务:

1
journalctl -u demo.service --since "30 min ago"

14.5 查看错误级别日志

1
journalctl -p err

当前启动周期的错误:

1
journalctl -b -p err

日志优先级从严重到详细大致为:

1
2
3
4
5
6
7
8
emerg
alert
crit
err
warning
notice
info
debug

14.6 查看内核日志

1
journalctl -k

上一次启动的内核日志:

1
journalctl -k -b -1

十五、控制 journal 日志磁盘占用

查看日志占用空间:

1
journalctl --disk-usage

按大小清理:

1
sudo journalctl --vacuum-size=1G

按时间清理:

1
sudo journalctl --vacuum-time=30d

journald 的主要配置文件通常是:

1
/etc/systemd/journald.conf

如果日志量很大,生产环境应根据磁盘大小、审计要求和日志平台策略统一设置,而不是等 /var 爆满以后再临时清理。


十六、排查一个 systemd 服务为什么启动失败

遇到:

1
Job for xxx.service failed

不要第一反应反复执行:

1
2
3
systemctl restart xxx
systemctl restart xxx
systemctl restart xxx

建议按下面顺序排查。

第一步:看状态

1
systemctl status xxx.service

关注:

1
2
3
4
5
Loaded:
Active:
Main PID:
Process:
Result:

第二步:看详细日志

1
journalctl -u xxx.service -n 200 --no-pager

或者:

1
journalctl -xeu xxx.service

第三步:检查 Unit 定义

1
systemctl cat xxx.service

确认:

  • ExecStart 路径是否正确;
  • 用户是否有权限;
  • WorkingDirectory 是否存在;
  • EnvironmentFile 是否存在;
  • 端口是否被占用;
  • 依赖服务是否正常;
  • Unit 是否被 mask。

第四步:检查依赖关系

1
systemctl list-dependencies xxx.service

反向查看谁依赖它:

1
systemctl list-dependencies --reverse xxx.service

第五步:验证 Unit 文件

1
systemd-analyze verify /etc/systemd/system/xxx.service

第六步:必要时清除 failed 状态

1
systemctl reset-failed xxx.service

这套顺序通常比“重启大法”有效得多。


十七、systemd-analyze:分析 Linux 为什么启动慢

systemd 还提供启动性能分析工具。

17.1 查看整体启动时间

1
systemd-analyze time

或者直接:

1
systemd-analyze

17.2 查看各 Unit 启动耗时

1
systemd-analyze blame

它会按照耗时排序。

但要注意:systemd 会并行启动大量 Unit,因此“某个服务自己启动花了 10 秒”不一定等于“它让系统整体启动慢了 10 秒”。

所以不能只看 blame。

17.3 查看关键依赖链

1
systemd-analyze critical-chain

它更适合判断某个 Target 的关键启动路径。

查看指定 Unit:

1
systemd-analyze critical-chain nginx.service

17.4 生成启动时序图

1
systemd-analyze plot > boot.svg

然后可以直接打开 boot.svg,从时间轴观察各 Unit 的启动关系。

如果真的要优化启动速度,通常需要把:

1
2
3
4
5
6
7
blame
+
critical-chain
+
plot
+
journal

结合起来分析,而不是看到 blame 第一名就直接 disable。


十八、Socket、Path 和 Timer:systemd 不只是 Service

18.1 Socket 激活

传统模式:

1
2
3
4
5
启动服务

服务监听端口

等待请求

Socket Activation 可以变成:

1
2
3
4
5
systemd 先监听 Socket

真正出现请求

再激活对应 Service

这也是 systemd 支持按需启动的重要机制之一。

18.2 Path 激活

Path Unit 可以监控:

  • 文件是否出现;
  • 文件是否修改;
  • 目录是否发生变化。

然后触发相应 Service。

适合“某个文件出现后自动处理”这一类场景。

18.3 Timer Unit

Timer Unit 可以实现定时执行,并且与 Service、日志、依赖关系天然结合。

查看定时器:

1
systemctl list-timers

很多现代 Linux 发行版中的系统级周期任务已经大量采用:

1
2
3
xxx.timer
+
xxx.service

这种组合。

它不是必须取代 cron,但在需要统一 systemd 生命周期、依赖和日志管理时非常方便。


十九、几个非常实用的 systemctl 命令

查看失败 Unit:

1
systemctl --failed

查看正在运行的服务:

1
systemctl list-units --type=service --state=running

查看服务完整配置:

1
systemctl cat sshd.service

查看服务属性:

1
systemctl show sshd.service

查看依赖:

1
systemctl list-dependencies sshd.service

查看默认 Target:

1
systemctl get-default

重载 systemd Unit:

1
systemctl daemon-reload

让 systemd 重新执行自身管理器进程,通常日常修改 Unit 不需要使用:

1
systemctl daemon-reexec

关机:

1
systemctl poweroff

重启:

1
systemctl reboot

挂起:

1
systemctl suspend

进入救援模式:

1
systemctl rescue

二十、生产环境编写 Service 的建议

20.1 使用专用用户运行应用

不要所有业务服务都写:

1
User=root

应该为应用创建独立用户:

1
2
User=demo
Group=demo

把最小权限原则真正落到进程级别。

20.2 使用绝对路径

推荐:

1
ExecStart=/usr/bin/java -jar /opt/demo/demo.jar

不要依赖登录 Shell 中的 PATH。

20.3 配置 WorkingDirectory

如果应用依赖相对路径:

1
WorkingDirectory=/opt/demo

否则从终端能运行,放到 systemd 里却报找不到配置文件,是非常典型的问题。

20.4 环境变量放 EnvironmentFile

例如:

1
EnvironmentFile=-/etc/demo/demo.env

- 前缀表示文件不存在时不因此直接失败。

相比把数据库地址、JVM 参数等全部硬编码进 Unit,独立环境文件通常更便于维护。

20.5 明确重启策略

1
2
Restart=on-failure
RestartSec=5s

不要依赖外部无限循环脚本自己守护。

20.6 让应用输出到 stdout/stderr

普通服务通常可以直接让应用写标准输出和标准错误,交给 journald 收集。

这样:

1
journalctl -u demo.service

就能直接排查。

如果企业已经统一接入 ELK、Loki、Splunk 等日志平台,再根据平台架构决定由 journald 转发还是应用输出独立日志文件。

20.7 可以逐步增加安全限制

确认应用兼容以后,可以考虑:

1
2
3
4
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

如果应用确实需要写目录,则再显式开放:

1
ReadWritePaths=/opt/demo/data

安全限制不要一次性全开,否则很容易把应用自己锁在门外。生产上建议一项一项验证。


二十一、一个更完整的应用 Service 模板

下面这个模板适合作为自研后台服务的起点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Unit]
Description=My Application Service
Documentation=https://example.com/docs
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp

EnvironmentFile=-/etc/myapp/myapp.env

ExecStart=/opt/myapp/bin/myapp

Restart=on-failure
RestartSec=5s
TimeoutStartSec=60s
TimeoutStopSec=30s

NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

部署流程:

1
2
3
sudo cp myapp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service

检查:

1
2
systemctl status myapp.service
journalctl -u myapp.service -n 100 --no-pager

升级应用:

1
sudo systemctl restart myapp.service

如果只修改了 Unit 文件:

1
2
sudo systemctl daemon-reload
sudo systemctl restart myapp.service

二十二、systemd 常见误区总结

误区一:start 以后就是开机自启动

不是。

1
2
start  = 现在启动
enable = 建立自动启动关系

需要两者一起:

1
systemctl enable --now xxx

误区二:After 就代表依赖

不是。

1
2
After/Before     = 顺序
Wants/Requires = 依赖

误区三:修改 Unit 后只 restart

应该:

1
2
systemctl daemon-reload
systemctl restart xxx

误区四:systemd 服务必须用 nohup

恰恰相反。

应用应该保持前台运行,让 systemd 负责守护。

误区五:服务失败只看 systemctl status

status 主要是入口。

进一步应该看:

1
journalctl -xeu xxx.service

误区六:blame 第一名就是启动慢的罪魁祸首

不一定。

systemd 大量并行启动,需要结合:

1
systemd-analyze critical-chain

甚至:

1
systemd-analyze plot

一起判断。


总结

掌握 systemd,最重要的不是记住几十个命令,而是理解下面这几个核心关系:

1
2
3
4
5
6
7
8
9
10
11
12
Linux Kernel

systemd(PID 1)

Unit
├── service
├── socket
├── target
├── timer
├── mount
├── path
└── ...

服务之间再通过:

1
2
3
Wants / Requires
After / Before
Conflicts

建立依赖和顺序关系。

日常操作主要依赖:

1
2
3
systemctl      服务和 Unit 管理
journalctl 日志查询
systemd-analyze 启动和依赖分析

对于服务器运维和应用部署来说,真正高频的操作可以浓缩成下面几条:

1
2
3
4
5
6
7
8
systemctl status xxx
systemctl restart xxx
systemctl enable --now xxx
systemctl daemon-reload
journalctl -xeu xxx
journalctl -u xxx -f
systemctl --failed
systemd-analyze critical-chain

当我们开始把应用直接以前台进程交给 systemd 管理,并使用 Unit 描述依赖、重启策略、运行用户、日志和启动顺序以后,Linux 服务管理就不再是“各种启动脚本拼起来能跑就行”,而真正变成了一套结构化、可观测、可维护的服务生命周期管理体系。

参考资料

本文基于以下资料进行知识抽取、去重和重新组织,并结合现代 systemd 常用实践进行了补充整理:

  1. CSDN:systemd
    https://blog.csdn.net/a624731186/article/details/22690947
  2. CSDN:关于 Systemd
    https://blog.csdn.net/m0_52316372/article/details/145530053
  3. 博客园:systemd 详解
    https://www.cnblogs.com/KrillLiszt/p/16192522.html
  4. systemd 官方文档与源码说明
    https://www.freedesktop.org/software/systemd/man/

Linux systemd 从入门到实战:Unit、systemctl、Service 与日志排障
https://allendericdalexander.github.io/2026/08/13/devops/linux/linux-systemd-guide/
作者
AtLuoFu
发布于
2026年8月13日
许可协议