Systemd 学习总结

儿时练功易,老来学艺难。

导航

  • 0 前言
  • 1 工具介绍
  • 2 配置结构
  • 3 Unit 实例
    • 3.0 通用块
      • 3.0.1 Unit 块参数
      • 3.0.2 Install 块参数
    • 3.1 Service
    • 3.2 Target
    • 3.3 Timer
    • 3.4 Path
    • 3.5 Slice
    • 3.5 Mount
    • 3.6 Automount
  • 4 命令管理
    • 4.1 systemctl 命令用法
    • 4.2 journalctl 命令用法
  • 5 杂七杂八

0、前言

当我们打开 Linux 主机以命令行模式或图形化模式进入系统之后,系统就已经为我们提供了很多的服务,如:打印服务、计划任务服务、邮件服务等等,那么这些服务是如何被启动起来的呢?在此之前我们先了解一下Linux 主机的启动过程

  1. 点击主机开机按钮,CPU 开始加载固件程序(即 BIOS 上电自检),待加载完毕之后 BIOS 便获得了 CPU 的控制权,然后 BIOS 会去加载开机启动顺序中指定的系统入口点(安装系统的光驱、硬盘的入口点)。
  2. 待 BIOS 加载了入口点处的引导装载程序 (GRUB2)之后,CPU 控制权此时便到了 GRUB2 的手里,GRUB2 接着开始加载硬盘中安装的 Linux 内核。
  3. 待 Linux 内核初始化完成之后,CPU 的控制权此时便到了 Linux 内核手中,往后 CPU 的控制权便一直掌握在 Linux 内核手中。
  4. 但 Linux 内核对于用户来说并不可直接被使用、而且也并未提供什么功能,于是它又雇佣了一个管家(init、systemd)并授予了一些权利,来代替它去做一些系统管理的事情。而这个管家便是 Linux 内核掌权之后启动的第一个外部程序,也是未来所有其它进程之父。

早期各 Linux 发行商为自家 Linux 内核配备的管家是init这个程序,该管家的特点是:(1)基于脚本式的方式去管理服务,服务的启动/停止/状态查看都是通过 /etc/init.d/ 下的 bash 脚本来实现的。(2)开机启动各种服务的时候,只能一个一个依序进行,不能够并行启动。(3)服务之间的依赖问题需要管理员手动处理。(4)系统环境切换依赖于 /etc/rc*.d/ 中的脚本。

如今各 Linux 发行商为自家 Linux 内核配备的管家基本都是systemd这个程序,该管家的特点是:(1)基于配置文件(服务单位 Unit )的方式去管理服务,服务的管理更灵活、更简单。(2)支持并行启动开机自启应用。(3)服务之间的依赖会自动检查,并自动唤醒。(4)兼容旧有的 init 服务脚本启动方式。

由于如今的 Linux 使用的服务管理方式多是 Systemd,因此学会它还是很有必要的。

注:Linxu 内核启动的第一个程序是 systemd,而 systemd 启动的第一个服务单元是 default.target,它一般被命令systemctl set-default multi-user.target链接到了 multi-user.target 或 graphical.target。

当 systemd 启动任何服务单元 Unit 文件的时候,systemd 首先去启动参数 Requires 和目录/etc/systemd/system/a.target.requires/关联的服务,然后再开始启动参数 Wants 和目录/etc/systemd/system/a.target.want/关联的服务。

systemd 找寻 default.target 单元文件时的目录查找顺序: /etc/systemd/system/default.target ↓ /run/systemd/system/default.target ↓ /usr/local/lib/systemd/system/default.target ↓ /usr/lib/systemd/system/default.target ↓ /lib/systemd/system/default.target

1、工具介绍

Systemd 是基于服务单位 Unit 来管理守护进程和系统资源的,它将这些服务单位 Unit 划分成了 service、target、timer、path、socket 等 12 种不同的类型,每种类型分别对应着不同的功能和应用场景以方便管理员使用。此外,Systemd 还维护着一个名为 journald 的日志系统来记录它所管理的服务在运行时产生的各种日志信息。

如图所见,Systemd 在 Linux 系统中的地位很重要,因为它必须确保系统启动并准备就绪,所以它承担的事情也比较多,例如:

  • 它会启动所有你需要的后台服务,例如网络、打印、容器、数据库等。【后台服务管理】
  • 它会自动挂载所有不同的文件系统和磁盘,以便可以随时访问。【开机挂载】
  • 一旦进入图形提示符,它就会处理用户登录、息屏和关机。【用户登录与会话管理】
  • 它会自动清理临时垃圾文件,或者每天自动备份数据。【定时任务】
  • 它会实时收集并归档内核、系统服务以及各种软件打印出来的日志。【日志记录】

2、配置结构

Systemd 管理的服务所对应的服务单元 Unit 文件的存放路径如下(注:这些路径存在优先级覆盖关系):

目录路径作用与特点适用场景
/etc/systemd/system/最高优先级。存放管理员手动创建或修改的单元文件,以及开机自启服务的软链接。用户自定义服务、修改系统默认配置。
/run/systemd/system/中等优先级。存放系统运行期间动态生成的临时单元文件(重启后丢弃)。程序运行时临时产生的服务、挂载点。
/lib/systemd/system/(或/usr/lib/systemd/system/)最低优先级。存放通过软件包管理器(如aptdnf)安装的服务默认配置。系统与软件自带的原始配置,请勿直接修改

此外,在修改单元配置文件时,官方建议不要直接在源文件(即/usr/lib/systemd/system/*中的单元文件)中进行修改,而是优先在/etc/systemd/system/*中进行修改。例如,如果你想额外修改 vsftpd.service 的话,则应该按如下方式处理:

目录路径作用说明
/usr/lib/systemd/system/vsftpd.service官方释出的预设设定档,不要动。
/etc/systemd/system/vsftpd.service.d/custom.conf在 /etc/systemd/system 底下建立与设定档相同档名的目录,但是要加上 .d 的副档名。然后在该目录下建立设定档即可。另外,设定档最好附档名取名为 .conf 较佳! 在这个目录下的档案会“累加其他设定”进入 /usr/lib/systemd/system/vsftpd.service 内。
/etc/systemd/system/vsftpd.service.wants/*此目录内的档案为连结档,设定相依服务的连结。意思是启动了 vsftpd.service 之后,最好再加上这目录底下建议的服务。
/etc/systemd/system/vsftpd.service.requires/*此目录内的档案为连结档,设定相依服务的连结。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。

最终,当执行systemctl start vsftpd.service命令时,systemctl 会将以上 4 个目录文件中的配置信息都聚合起来形成一份运行时 service 服务单元去执行。不过这种用法个人觉得还是太麻烦,还不如直接拷贝一份源文件在/etc/systemd/system/vsftpd.service然后直接修改它来的容易。

3、Unit 实例

Systemd 所划分的 12 种 Unit 类型如下:

Unit 类型文件后缀作用常见用途
Service Unit.service管理系统服务/进程启动 nginx、docker、ssh
Target Unit.target管理一组 Unit 的集合类似运行级别
Timer Unit.timer定时任务替代 cron
Path Unit.path监控文件路径变化文件变化触发任务
Slice Unit.slice管理资源分组CPU/内存限制
Mount Unit.mount管理文件系统挂载自动挂载磁盘
Automount Unit.automount按需挂载文件系统延迟挂载
Swap Unit.swap管理 swap 分区/文件开启交换空间
Scope Unit.scope管理外部进程用户会话、容器
Socket Unit.socket管理 socket 通信socket 激活服务
Device Unit.device管理硬件设备磁盘、USB 设备
Snapshot Unit.snapshot保存当前状态系统状态快照

3.0、通用块

每种 Unit 配置文件的语法格式基本都是由 3 大块组成:通用的【Unit 块 + Install 块】,以及独属于每种 Unit 类型专属的【Service 块、Timer 块、Path 块等】。下面我将展示通用块【Unit 块 + Install 块】的常用参数,而关于每种 Unit专属块的常用参数则在各自的小节进行展示。

3.0.1、Unit 块参数

【Unit 块】常用参数列表

设定参数参数意义说明
Description对当前 Unit 的功能进行简短描述,执行systemctl status时通常可以看到。
Documentation指定该 Unit 的相关文档地址,可以是man:info:或 URL。
Requires强依赖关系。当前 Unit 启动时,会尝试启动这里指定的 Unit;如果依赖 Unit 被停止或启动失败,当前 Unit 通常也会受到影响。
Wants弱依赖关系。当前 Unit 启动时,会尝试启动这里指定的 Unit;但依赖 Unit 启动失败,一般不会导致当前 Unit 失败。
Requisite要求指定 Unit 已经处于 active 状态,否则当前 Unit 不会启动;它本身不会主动启动依赖 Unit。
BindsToRequires更强的绑定关系。依赖 Unit 消失或变为 inactive 时,当前 Unit 也会停止。
PartOf建立停止/重启传播关系。当指定 Unit 被停止或重启时,当前 Unit 也会执行相应操作。
Conflicts表示两个 Unit 不能同时运行。启动一个 Unit 时,会停止与它存在Conflicts关系的 Unit。
Before指定当前 Unit 必须在某些 Unit之前启动。只负责启动顺序,不建立依赖关系。
After指定当前 Unit 必须在某些 Unit之后启动。只负责启动顺序,不建立依赖关系。
Before/After可以同时使用。例如After=network.target表示当前 Unit 的启动顺序排在network.target后面。
Condition...启动前进行条件检查。条件不满足时,Unit 会被跳过,而不是认为启动失败。
Assert...启动前进行断言检查。条件不满足时,Unit 启动会被认为失败。
DefaultDependencies是否自动添加 systemd 默认依赖关系,默认通常为yes
OnFailure当前 Unit 启动失败时,自动激活指定的 Unit。
OnSuccess当前 Unit 成功停止/完成后,自动激活指定的 Unit。
JobTimeoutSec设置等待该 Unit Job 完成的超时时间。
StartLimitIntervalSec在指定时间窗口内限制 Unit 的启动次数。
StartLimitBurst指定时间窗口内允许的最大启动次数,通常与StartLimitIntervalSec配合使用。
3.0.2、Install 块参数

【Install 块】常用参数列表

设定参数参数意义说明
WantedBy指定当前 Unit 应该被哪个 Target 以Wants关系拉起。执行systemctl enable时,会在对应 Target 的.wants/目录中创建符号链接。
RequiredByWantedBy类似,但建立的是Requires关系,启用当前 Unit 时会在对应 Target 的.requires/目录建立链接。
Also当执行systemctl enabledisable当前 Unit 时,同时对指定的其他 Unit 执行相应操作。
Alias为当前 Unit 创建别名。启用 Unit 时,会建立对应的符号链接,使得可以通过别名操作同一个 Unit。

3.1、Service

单元介绍:最基本的单元,主要用来启动服务进程,同时也是 target、timer、path、socket 这些单元所需的基本单元。

期望目标:一条命令启动/停止 nginx 服务进程。

# cat nginx.service [Unit] Description=Nginx Web Server After=network.target [Service] ExecStart=/usr/sbin/nginx ExecStop=/usr/sbin/nginx -s stop Restart=always [Install] WantedBy=multi-user.target

【Service 块】常用参数列表

设定参数参数意义说明
Type指定服务的启动类型,常见有simpleexecforkingoneshotdbusnotifyidle
ExecStart指定启动服务时执行的命令,是最核心的 Service 参数之一。
ExecStartPreExecStart之前执行的命令,常用于启动前检查或准备工作。
ExecStartPostExecStart成功后执行的命令。
ExecReload执行systemctl reload xxx时运行的命令,用于让程序重新加载配置。
ExecStop执行systemctl stop xxx时运行的命令。
ExecStopPost服务停止后执行的命令,常用于清理工作。
Restart指定服务退出后是否自动重新启动,例如noon-successon-failurealways
RestartSec服务自动重启前等待多长时间。
RestartPreventExitStatus指定某些退出状态码时禁止自动重启。
RestartForceExitStatus指定某些退出状态码时强制触发自动重启。
User指定服务进程以哪个用户身份运行。
Group指定服务进程使用的用户组。
WorkingDirectory指定服务进程的工作目录。
Environment设置服务运行时的环境变量。
EnvironmentFile从指定文件读取环境变量。
ExecSearchPath指定执行程序时搜索可执行文件的路径。
PIDFile指定服务 PID 文件的位置,常用于Type=forking的服务。
RemainAfterExitType=oneshot等服务有用,表示命令执行结束后 Unit 是否继续保持 active 状态。
TimeoutStartSec设置服务启动超时时间。
TimeoutStopSec设置服务停止超时时间。
TimeoutAbortSec服务被中止时允许等待的时间。
KillMode指定停止服务时 systemd 如何处理服务进程,例如control-groupprocessmixed
KillSignal指定停止服务时首先发送的信号,默认通常为SIGTERM
SuccessExitStatus指定哪些退出状态被认为是正常退出。
StandardOutput指定标准输出的去向,例如journalnullfile:等。
StandardError指定标准错误输出的去向。
SyslogIdentifier设置写入 journal 时使用的标识名称。
Nice设置进程的 CPU 调度优先级。
OOMScoreAdjust调整进程被 Linux OOM Killer 杀死时的优先级。
LimitNOFILE限制进程能够打开的最大文件描述符数量。
LimitNPROC限制进程能够创建的进程/线程数量。
PrivateTmp为服务提供独立的/tmp/var/tmp环境。
ProtectSystem限制服务对系统目录的写权限,提高安全性。
ProtectHome限制服务访问/home/root/run/user等目录。
NoNewPrivileges禁止服务进程通过execve()获取新的特权,提高安全性。

由于Type[Service]中非常重要的参数,因此下面将对该参数进行详细说明:

Type含义
simpleExecStart启动的进程就是主进程,systemd 启动命令后通常就认为服务已经启动。
exec类似simple,但会等待程序真正成功执行后再认为启动成功。
forking程序启动后会 fork 到后台,传统守护进程常使用这种方式。
oneshot执行一次命令后退出,常用于脚本、初始化任务。
notify程序通过 systemd 的通知机制主动告诉 systemd “我已经启动完成”。
dbus程序成功获得指定 D-Bus 名称后认为启动完成。
idle等待其他任务完成后再启动,主要用于调整启动时机。

3.2、Target

单元介绍:搭配 service 或其他类型的 Unit 使用,可以理解为是一组 Unit 的集合,它本身通常不执行程序,而是用来组织和控制多个 service、mount、socket 等 Unit 的启动顺序。

期望目标:通过一条命令便可同时启动这些 web 业务服务:nginx、mysql、redis。

# cat nginx.service mysql.service redis.service...省略...
# cat myapp.target [Unit] Description=My Application Stack Requires=nginx.service mysql.service redis.service After=nginx.service mysql.service redis.service

【Target 块】常用参数列表

注:该 Unit 的配置文件无专属块参数,只需要通用的 Unit、Install 块即可。

3.3、Timer

单元介绍:搭配 service 使用,可以理解为是 service 的专属定时器,时间单位可精细到秒。【注:cron 的最小时间单位是分钟】

期望目标:定时执行服务程序。

# cat backup.service [Unit] Description=backup file [Service] Type=oneshot ExecStart=/usr/local/bin/file-backup.sh
# cat backup.timer [Unit] Description=backup my server timer [Timer] OnBootSec=2hrs # 开机后 2 小时开始执行一次这个 backup.service。 OnUnitActiveSec=2days # 自从第一次执行后,未来每两天要执行一次 backup.service。 [Install] WantedBy=multi-user.target

注:持续计时参数。

# 每天凌晨执行备份。 [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true

【Timer 块】常用参数列表

设定参数参数意义说明
OnBootSec系统启动后经过指定时间后触发 Timer,例如OnBootSec=5min表示系统启动 5 分钟后执行。
OnStartupSecsystemd 用户实例或系统实例启动后经过指定时间触发。系统级 Timer 中通常与OnBootSec类似。
OnUnitActiveSec被触发的 Unit上一次被激活后,经过指定时间再次触发。例如OnUnitActiveSec=1h表示服务激活后每隔 1 小时再次触发。
OnUnitInactiveSec被触发的 Unit变为 inactive 后,经过指定时间再次触发。
OnCalendar按日历时间触发,例如OnCalendar=dailyOnCalendar=*-*-* 02:00:00
OnActiveSecTimer 本身被激活后经过指定时间触发。
OnFailureSecTimer 所关联的 Unit 失败后经过指定时间触发。
Persistent是否补执行错过的任务。设置为true后,如果机器关机期间错过了定时任务,下一次启动时会补执行。
AccuracySecTimer 触发时间允许的误差范围,用于让 systemd 合并多个定时任务以减少系统唤醒。
RandomizedDelaySec在计划触发时间基础上增加随机延迟,可避免大量机器同时执行任务。
Unit指定 Timer 触发哪个 Unit。默认情况下,xxx.timer通常触发同名的xxx.service

3.4、Path

单元介绍:搭配 service 使用,当某个文件的内容/状态出现变动时,触发对绑定 service 的启动。

期望目标:当文件/tmp/test.txt被修改(echo hello >> /tmp/test.txt)时,系统会自动执行 file-change.sh 脚本。

# cat file-change.service [Unit] Description=Handle file change [Service] Type=oneshot ExecStart=/usr/local/bin/file-change.sh
# cat file-change.path [Unit] Description=Monitor test file [Path] PathModified=/tmp/test.txt [Install] WantedBy=multi-user.target

【Path 块】常用参数列表

设定参数参数意义说明
PathExists指定路径存在时触发关联的 Service。
PathExistsGlob使用通配符匹配路径,只要匹配的路径存在就触发 Service。
PathChanged指定文件或目录发生变化时触发 Service。
PathModified指定文件被修改时触发 Service。相比PathChanged,更关注文件内容修改。
DirectoryNotEmpty指定目录不为空时触发 Service,常用于监控“文件投递目录”。
Unit指定 Path Unit 触发哪个 Unit。默认情况下,xxx.path通常触发同名的xxx.service
MakeDirectory创建监控路径不存在的父目录。

3.5、Slice

单元介绍:搭配 service 使用,让加入到同一个资源组的服务共用同一个环境的资源,可以起到限制进程无限使用系统资源的作用。

期望目标:让 nginx 服务所能使用的最大 CPU 不超过 40%,最大内存不超过 2G。

# cat nginx.service [Unit] Description=Nginx Web Server After=network.target [Service] ExecStart=/usr/sbin/nginx ExecStop=/usr/sbin/nginx -s stop Restart=always Slice=web.slice [Install] WantedBy=multi-user.target
# cat web.slice [Slice] CPUQuota=40% MemoryMax=2G

【Slice 块】常用参数列表

设定参数参数意义说明
CPUQuota限制该 Slice 最多使用多少 CPU,例如CPUQuota=50%表示最多使用 50% 的一个 CPU 核心。
MemoryMax设置该 Slice 可使用的最大内存,超过限制后可能触发 OOM 处理。
MemoryHigh设置内存使用的“高水位”,超过后 systemd 会对该 Slice 施加内存压力控制,但通常不会像MemoryMax那样直接作为硬限制。
MemoryMin设置该 Slice 应获得的最低内存保障。
MemoryLow设置内存保护的低水位。
TasksMax限制该 Slice 中最多允许创建多少个进程/线程。
IOWeight设置磁盘 I/O 权重,用于不同 Slice 之间的 I/O 资源竞争。
IODeviceWeight针对特定设备设置 I/O 权重。
BlockIOAccounting是否统计该 Slice 的块设备 I/O 使用情况。
CPUAccounting是否统计 CPU 使用情况。
MemoryAccounting是否统计内存使用情况。
TasksAccounting是否统计任务数量。

3.6、Mount

单元介绍:该 Unit 相当于是对系统 fatab/mount 的另一种实现,同时也是 Automount 自动挂载单元的基本 Unit。

期望目标:通过systemctl start data.mount将 sdb1 这个分区挂载到 /data 目录下。

# cat data.mount [Unit] Description=Mount data disk [Mount] What=/dev/sdb1 Where=/data Type=ext4 Options=defaults [Install] WantedBy=multi-user.target

【Mount 块】常用参数列表

设定参数参数意义说明
What指定要挂载的设备、磁盘分区、LVM、NFS 等来源,例如/dev/sdb1
Where指定挂载点,例如/data。这是 Mount Unit 最核心的参数之一。
Type指定文件系统类型,例如ext4xfsnfs等。
Options指定挂载参数,相当于mount -o后面的参数,例如defaults,noatime
SloppyOptions是否允许部分无法识别的挂载选项被忽略。
LazyUnmountUnit 停止时是否使用 lazy unmount。
ForceUnmountUnit 停止时是否强制卸载。
DirectoryMode如果挂载点目录不存在,指定创建目录时使用的权限。
TimeoutSec设置挂载操作的超时时间。

3.7、Automount

单元介绍:搭配 mount 单元使用,当指定的目录被读取时,自动触发对绑定 mount 的启动。

期望目标:正常情况下,backup.mount 这个分区并不会被挂载,但是当执行ls /backup的时候,这个分区才会被挂载。

# cat backup.mount [Unit] Description=NFS Backup Mount [Mount] What=192.168.1.10:/backup Where=/backup Type=nfs Options=defaults # 注意,这里没有配置 WantedBy= 选项,因为它不需要通过开机启动。
# cat backup.automount [Unit] Description=Automount backup directory [Automount] Where=/backup TimeoutIdleSec=300 [Install] WantedBy=multi-user.target

注:mount 一般用于开机自启,而 automount 则用于按需自启。

【Automount 块】常用参数列表

设定参数参数意义说明
Where指定自动挂载点,例如/data
DirectoryMode如果挂载点目录不存在,指定创建目录时的权限。
TimeoutIdleSec指定挂载点空闲多长时间后自动卸载。例如TimeoutIdleSec=10min

4、命令管理

4.1、systemctl 命令用法

systemd 用来管理服务的命令只有一条,即 systemctl,以下便是关于该命令最常见的用法:

# -------------------- 1. 服务管理 --------------------# 启动/停止/重启/重载/查看服务systemctl start/stop/restart/reload/status nginx# 设置/取消/开机自启,以及禁止/取消禁止服务被自启systemctl enable/disable/mask/unmask nginx# 判断服务 是否自启/是否正在运行/是否启动失败systemctl is-enabled/is-active/is-failed nginx# -------------------- 2. 服务状态查看 --------------------# 查看系统中所有已安装的 Unit 文件的预设状态systemctl list-unit-files# 查看所有 Unit 的运行状态,包括 inactivesystemctl list-units--all# 按 Unit 类型查看当前启动的 Unitsystemctl list-units--type=service systemctl list-units--type=socket systemctl list-units--type=timer systemctl list-units--type=mount systemctl list-units--type=target# 查看启动失败的 Unitsystemctl list-units--state=failed# 等价于 systemctl --failed# 查看所有 Socket 服务的状态,不论是否启动systemctl list-sockets# 查看所有 Timer 服务的状态,不论是否启动systemctl list-timers# 查看所有 Path 服务的状态,不论是否启动systemctl list-paths# 查看所有 Automount 服务的状态,不论是否启动systemctl list-automounts# -------------------- 3. Unit 文件管理 --------------------# 查看 Unit 的属性信息systemctl show nginx# 查看 Unit 文件内容systemctlcatnginx# 编辑 Unit 文件(修改内容会被添加到 /etc/systemd/system/nginx.service.d/override.conf 文件中)systemctl edit nginx# 编辑完整 Unit 文件(可直接在原来的基础上进行修改)systemctl edit--fullnginx# 修改 Unit 文件后重新加载 systemdsystemctl daemon-reload# -------------------- 4. Unit 依赖查询 --------------------# 查看 Unit 的依赖关系systemctl list-dependencies nginx# 查看反向依赖systemctl list-dependencies--reversenginx# -------------------- 5. Target 管理 --------------------# 查看默认 Targetsystemctl get-default# 设置默认 Targetsystemctl set-default multi-user.target# 切换到指定 Targetsystemctl isolate multi-user.target# 查看 Target 的依赖systemctl list-dependencies multi-user.target# -------------------- 6. 系统操作 --------------------# 重启系统systemctlreboot# 关机systemctl poweroff# 挂起systemctlsuspend# 休眠systemctl hibernate# 进入救援模式systemctl rescue# 进入紧急模式systemctl emergency

4.2、journalctl 命令用法

前面我们说过,systemd 不仅可以用来管理服务,同时它还提供了一个日志记录服务 journald 来记录服务单元的日志活动,而查看日志的命令也只有一条,即 journalctl,以下便是关于该命令最常见的用法:

# -------------------- 1. 查看日志 --------------------# 查看全部日志journalctl# 查看当前启动的内核日志journalctl-k# 查看指定服务的全部日志journalctl-unginx# 查看最近 N 条日志journalctl-n50# 查看最新日志并自动跳到末尾journalctl-e# 实时跟踪日志(类似 tail -f)journalctl-f# 显示完整时间等信息journalctl-oshort-full# -------------------- 2. 按时间查看日志 --------------------# 查看今天的日志journalctl--sincetoday# 查看最近 30 分钟的日志journalctl--since"30 min ago"# 查看指定时间之后的日志journalctl--since"2026-08-11 10:00:00"# 查看指定时间之前的日志journalctl--until"2026-08-11 12:00:00"# 查看指定时间范围的日志journalctl--since"2026-08-11 10:00:00"--until"2026-08-11 12:00:00"# 查看某服务最近 1 小时的日志journalctl-unginx--sincetoday# -------------------- 3. 按日志级别过滤 --------------------# 查看 error 及更严重的日志journalctl-perr# 查看 warning 到 emergencyjournalctl-pwarning..emerg# 常见日志级别:## 0 emerg 紧急# 1 alert 必须立即处理# 2 crit 严重错误# 3 err 错误# 4 warning 警告# 5 notice 注意# 6 info 信息# 7 debug 调试# -------------------- 4. 按关键词搜索 --------------------# 搜索包含关键字的日志journalctl-g"error"# 搜索指定服务中的关键词journalctl-unginx-g"error"# 忽略大小写搜索journalctl-g"error"--case-sensitive=false# -------------------- 5. 日志空间占用 --------------------# 查看 journal 日志占用空间journalctl --disk-usage# 删除超过指定时间的日志journalctl --vacuum-time=30d

5、杂七杂八

(1)参考文档:阮一峰的网络日志、ArchWiki、官方手册

(2)systemctl 子命令 daemon-reload 和 reload 的区别 :

命令功能
systemctl daemon-reload让 systemd 重新读取 Unit 配置文件,以便 systemctl 在管理服务的时候能够按照最新的 Unit 配置文件内容做出反应。
systemctl reload nginx.service让某个正在运行的服务重新加载自己的配置文件,例如:让 nginx 服务重新加载自己的配置文件 nginx.conf 的参数内容。

(3)为什么执行开机自启命令systemctl enable *.service的时候,命令会在/etc/systemd/system/multi-user.target.wants/目录中添加服务的软链接?

开机自启说白了就是让服务能够跟随 multi-user.target 服务单元一起被启动,而在服务单元 Unit 的配置文件中,这一功能是可以通过参数 Wants 实现的,因此你是可以通过修改/etc/systemd/system/multi-user.target配置文件来做到让指定服务开机自启的。

但我们前面也说过,系统预置的 Unit 文件一般不要随便改动。于是官方又为其设计了/etc/systemd/system/multi-user.target.wants/目录,其功能与 Unit 文件中的 Wants 参数的作用是一样的,不用随便修改文件只需把指定服务的软链接放进去就可以,也不用老是在修改完 Unit 文件之后需要频繁执行systemctl daemon-reload加载信息,可谓是相当灵活。

注:服务对应的 Unit 文件(此处以 nginx.service 为例)中 [Install] 块下的WantedBy = multi-user.target是指,当执行systemctl enable nginx.service时,便会为 nginx.service 创建软链接,链接目标便是在 multi-user.target 的 wants 文件夹下面,即/etc/systemd/system/multi-user.target

(4)Unit 模板单元示例(此处以 vsftpd 为例):

以前,如果我们想运行多个 FTP 实例,那我们会为其配置多个配置文件(如 ftpd1.conf、ftpd2.conf、ftpd3.conf 等),然后按照vsftpd /etc/vsftpd/ftpd1.confvsftpd /etc/vsftpd/ftpd2.confvsftpd /etc/vsftpd/ftpd3.conf的方式去一一启动。

但现在,我们管理服务都是通过 systemd 进行的,那该如何实现通过 systemctl 达到一键开启多个实例的效果呢?这就轮到 Unit 模板单元来展示了。

用法其实也很简单,就是将常规的 vsftpd.service 文件中关于配置文件变动的地方改成变量的形式就好了,如下:

# cat /usr/lib/systemd/system/vsftpd@.service [Unit] Description=Vsftpd ftp daemon After=network.target PartOf=vsftpd.target [Service] Type=forking ExecStart=/usr/sbin/vsftpd /etc/vsftpd/ftpd%I.conf #[Install] #WantedBy=vsftpd.target # 注意:该配置来自鸟哥私房菜。此处并非是 multi-user.target,而是一个自建的 vsftpd.target,这一点似乎有说法,但我觉得直接注释即可,作用不大。

如此一来,我们想启动 ftpd2.conf 配置文件的实例就执行systemctl start vsftpd@2.service,想启动 ftpd3.conf 的实例,就执行systemctl start vsftpd@3.service。可这样还是有个不方便的地方,那就是如果我们想将三个实例都启动起来,就需要连续执行 3 次启动命令,而且这种模板服务似乎也不能够进行开机自启。

注:在systemctl start vsftpd@1.service中,@后面的字串会被当做参数赋值给配置文件中的变量%I

这时候我们就可以用到 target 这个 Unit 了,让它来帮我们实现一键启动多个模板实例的效果。

我的博客园