Linux 系统服务管理器 Systemd 及命令 systemctl 的详细介绍

2021/5/6 7:27:37

本文主要是介绍Linux 系统服务管理器 Systemd 及命令 systemctl 的详细介绍,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 一、系统服务管理器 Systemd
    • (一)Systemd 的特性
    • (二)Systemd 与 传统 init 系统的区别
    • (三)Systemd 的目录和文件
    • (四)Systemd 的 Unit 介绍
      • 1.Unit 类型
      • 2.Unit 的配置文件
        • (1)配置文件的状态
        • (2)配置文件的格式
        • (4)配置文件的区块
      • 3.Unit 的依赖管理
    • (五)Systemd 的 Target 介绍
      • 1.查看当前系统的所有 Target
      • 2.查看一个 Target 包含的所有 Unit
      • 3.查看启动时的默认 Target
      • 4.设置启动时的默认 Target
      • 5.切换 Target
      • 6.Target 与 传统 Run Level 的对应关系
    • (六)Systemd 并行启动原理
      • 并发启动原理之一:解决 socket 依赖
      • 并发启动原理之二:解决 D-Bus 依赖
      • 并发启动原理之三:解决文件系统依赖
    • (七)Systemd 配置使用
      • 1.对于系统开发人员
      • 2.对于系统管理员
  • 二、使用命令 systemctl 管理系统服务
    • (一)命令介绍
    • (二)命令选项
    • (三)Systemd 命令和 SysV init 命令的对比
    • (四)命令示例
      • 1.重启 restart
      • 2.纯重启 try-restart
      • 3.重新加载 reload
      • 4.启动 start
      • 5.停止 stop
      • 6.查看服务状态 status
        • (1)解读服务状态信息
        • (2)关于服务的启动状态
        • (3)关于服务的运行状态
      • 7.开机启动 enable
      • 8.取消开机启动 disable
      • 9.查看是否开机启动 is-enabled
      • 10.查看启动失败的服务 -failed
      • 11.查看进程是不是在运行中 is-active
      • 12.查看系统中所有已经启动的服务
      • 13.根据目录 /lib/systemd/system/ 内的 service 文件查看系统的服务单元
      • 14.只看服务类型的 unit
      • 15.查看加载失败的 unit
      • 16.管理系统的操作环境(target unit)
        • (1)查看系统目前的操作模式(target)
        • (2)设置系统默认的操作模式
        • (3)切换操作模式
      • 17.让系统进入暂停模式
      • 18.让系统进入休眠模式
      • 19.强制系统进入救援模式
      • 20.强制系统进入紧急救援模式
      • 22.重新加载 systemd 程序的配置文件
      • 23.杀死服务
      • 24.管理系统挂载点的命令
      • 25.查看 systemd 的版本
      • 26.查看系统启动耗时
      • 27.查看每个进程在引导时花费的时间
      • 28.查看指定服务的关键链
      • 29.获取服务的依赖项列表
      • 30.按层次列出控制组
      • 31.根据CPU,内存,输入和输出列出控制组
      • 32.查看指定类型的 unit
      • 33.列出所有没有运行的 Unit
      • 34.查看系统状态
      • 35.显示远程主机的某个 Unit 的状态
      • 36.显示某个 Unit 是否处于启动失败状态
      • 37.重载所有修改过的配置文件
      • 38.显示某个 Unit 的指定属性的值
      • 39.设置某个 Unit 的指定属性
    • (六)systemctl 与 旧命令的对比

一、系统服务管理器 Systemd

init(initialization 的简写)是 Unix 和 类 Unix 系统中用来产生其它所有进程的程序。Linux 内核加载启动后,用户空间的第一个进程就是 init 进程,这个进程的进程号为1,代表第一个运行的用户空间进程,它作为父守护进程在运行,用户空间中的其它进程都是它的子进程。

Linux 系统在引导时加载 Linux 内核后,便由 Linux 内核加载 init 程序,由 init 程序完成余下的引导过程,比如加载运行级别,加载服务,引导 Shell/图形化界面等。

Systmed 是系统初始化程序,负责控制和管理系统服务,它其实是一个用户空间的程序,属于应用程序,不属于 Linux 内核范畴,Linux 内核的主要特征在所有发行版中是统一的,厂商可以自由改变的是用户空间的应用程序。以 Systemd 作为系统服务管理器(启动程序)的 Linux 系统开启后,Systemd 就是 init 进程。

Systemd 这一名字源于 Unix 中的一个惯例:在 Unix 中常以 d 作为系统守护进程的后缀标识。d 是英文单词 daemon(意指后台进程) 的首字母。

不同发行版采用了不同的启动程序:

(1)Ubuntu 的 Linux 发行版采用 Upstart。

(2)Red Hat 旗下的 7.0 版本之前的 CentOS 采用 System V init。

(3)Red Hat 旗下的 7.0 版本的 CentOS 采用 Systemd。

目前 Systemd 不仅在 Red Hat 旗下的 Linux 发行版中作为系统服务管理器,其它派系也开始使用 Systemd 作为最新发行版的初始化系统,代替常用的 System V 与 BSD 风格 init 程序。

(一)Systemd 的特性

开机时并行启动系统服务,极大地提高了系统启动速度

按需启动守护进程

支持系统状态快照

基于依赖的服务控制逻辑,自动化的服务依赖关系管理

用 CGroup 统计跟踪子进程,干净可靠

同时采用socket式与D-Bus总线式激活服务

(二)Systemd 与 传统 init 系统的区别

  1. systemd用目标(target)代替了System V init 中运行级别的概念

  2. 默认的 Run Level(在/etc/inittab文件设置)现在被默认的 Target 取代,由文件 /etc/systemd/system/default.target 定义,通常符号链接到 graphical.target(图形界面)或者 multi-user.target(多用户命令行)

  3. 启动脚本的位置,以前是 /etc/init.d 目录,符号链接到不同的 Run Level 目录 (比如 /etc/rc3.d、/etc/rc5.d 等),现在则存放在 /lib/systemd/system 和 /etc/systemd/system 目录下

  4. 配置文件的位置,以前 init 进程的配置文件是 /etc/inittab,各种服务的配置文件存放在 /etc/sysconfig 目录。现在的配置文件主要存放在/lib/systemd目录,在 /etc/systemd 目录里面的修改可以覆盖原始设置

(三)Systemd 的目录和文件

在不同的发行版中与 Systemd 相关的文件路径可能会不太一样,在此以 ubuntu 16.04 举例简单介绍如下:

  1. /lib/systemd/system/:大多数 unit 的配置文件都放在这个目录下,CentOS 则放在 /usr/lib/systemd/system/ 目录中,使用命令:systemctl list-unit-files 可以列出该目录下的所有配置文件。

  2. /etc/systemd/system/:这个目录中主要的文件都是指向 /lib/systemd/system/ 目录中的链接文件。注意,在我们自己创建 unit 配置文件时,既可以把配置文件放在 /lib/systemd/system/ 目录下,也可以放在 /etc/systemd/system/ 目录下。

  3. /run/systemd/system/:系统运行过程中产生的脚本,比如用户相关的脚本和会话相关的脚本。

  4. /etc/default/ 这个目录中放置很多服务默认的配置文件。

  5. /var/lib/ 一些会产生数据的服务都会将他的数据写入到 /var/lib/ 目录中,比如 docker 相关的数据文件就放在这个目录下。

  6. /bin/sbin 工具命令位于这两个目录下。

  7. /run/ 这个目录放置了好多服务运行时的临时数据,比如 lock file,PID file,socket file 等。

我们使用命令:systemctl list-sockets 查看下 socket 文件所存放的位置:

[root@htlwk0001host ~]# systemctl list-sockets
LISTEN                            UNIT                            ACTIVATES
/run/dbus/system_bus_socket       dbus.socket                     dbus.service
/run/dmeventd-client              dm-event.socket                 dm-event.service
/run/dmeventd-server              dm-event.socket                 dm-event.service
/run/initctl                      systemd-initctl.socket          systemd-initctl.service
/run/lvm/lvmpolld.socket          lvm2-lvmpolld.socket            lvm2-lvmpolld.service
/run/systemd/coredump             systemd-coredump.socket        
/run/systemd/journal/dev-log      systemd-journald-dev-log.socket systemd-journald.service
/run/systemd/journal/socket       systemd-journald.socket         systemd-journald.service
/run/systemd/journal/stdout       systemd-journald.socket         systemd-journald.service
/run/udev/control                 systemd-udevd-control.socket    systemd-udevd.service
/var/run/.heim_org.h5l.kcm-socket sssd-kcm.socket                 sssd-kcm.service
kobject-uevent 1                  systemd-udevd-kernel.socket     systemd-udevd.service

12 sockets listed.
Pass --all to see loaded but inactive sockets, too.

在 CentOS 系统下我们可以使用命令:rpm -ql systemd 查看 Systemd 的相关目录和文件:

[root@htlwk0001host ~]# rpm -ql systemd
/etc/X11/xinit/xinitrc.d/50-systemd-user.sh
/etc/X11/xorg.conf.d/00-keyboard.conf
/etc/binfmt.d
/etc/crypttab
/etc/dnf/protected.d/systemd.conf
/etc/hostname
/etc/inittab

文件 /etc/inittab 是 System V init 的标准配置文件,而使用 Systemd 作为 init 系统后,我们再看看这个文件的内容:

[root@htlwk0001host ~]# cat /etc/inittab
# inittab is no longer used.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target

如上的内容可以看到在 Systemd 掌权后,/etc/inittab 这个文件不再使用了,也没有了“运行级”的概念。现在起作用的配置文件是 /etc/systemd/system/default.target 这个文件了。此文件的内容如下:

[root@htlwk0001host ~]# cat /etc/systemd/system/default.target
#  SPDX-License-Identifier: LGPL-2.1+
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

(四)Systemd 的 Unit 介绍

Systemd 的核心概念是 Unit(单元),Unit 表示不同类型的 Systemd 对象,通过配置文件进行标识和配置。使用 SysV 或者 UpStart 初始化的 Linux 发行版,都是使用位于目录 /etc/rc.d/init.d/ 下的 bash 初始化脚本来对系统服务进行管理的,而使用 Systemd 作为初始化系统的 Linux 发行版(例如:RHEL 7.x、CentOS 7.x)则用服务单元(Service Unit)取代了这些启动脚本,服务单元是一种以 .service 作为扩展名的服务文件,提供了与初始化脚本同样的用途。

1.Unit 类型

Service:文件扩展名为.service, 用于定义系统服务

Target:Unit 的逻辑分组,包含多个相关的 Unit,用于模拟实现 System V 的运行级别

Device:用于定义内核识别的设备,对应 udev 规则标记的一个设备

Mount:定义文件系统挂载点,Systemd 据此进行自动挂载。为了与 System V init 兼容,目前 Systemd 自动处理 /etc/fstab 并转化为Mount

Socket:用于标识进程间通信用的 socket 文件,也可在系统启动时,延迟启动服务,实现按需启动

Snapshot:管理系统快照,与 Target 类似,表示当前的运行状态

Swap:用于标识 swap 设备

Automount:文件系统的自动挂载点

Path:用于定义文件系统中的一个文件或目录使用,常用于当文件系统变化时,延迟激活服务

Timer:定时器,用来定时触发用户定义的操作,它可以用来取代传统的 atd,crond 等

Scope:不是由 Systemd 启动的外部进程

Slice:进程组

2.Unit 的配置文件

每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit 。系统管理员的任务就是编写和维护这写不同的配置文件。

Systemd 默认从目录 /etc/systemd/system/ 读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录 /usr/lib/systemd/system/,该目录是配置文件存放的真正目录。

配置文件的后缀名,就是该 Unit 的种类,比如 sshd.socket。如果省略,Systemd 默认后缀名为.service,所以 sshd 会被理解成sshd.service。

一旦修改配置文件,就要让 Systemd 重新加载配置文件,然后重新启动,否则修改不会生效,例如:

$ sudo systemctl daemon-reload
$ sudo systemctl restart httpd.service

(1)配置文件的状态

一共有四种:
enabled:已建立启动链接
disabled:没建立启动链接
static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖
masked:该配置文件被禁止建立启动链接

(2)配置文件的格式

配置文件就是普通的文本文件,可以用文本编辑器打开。

systemctl cat命令可以查看配置文件的内容。

$ systemctl cat atd.service

[Unit]
Description=ATD daemon

[Service]
Type=forking
ExecStart=/usr/bin/atd

[Install]
WantedBy=multi-user.target

从上面的输出可以看到,配置文件分成几个区块。每个区块的第一行,是用方括号表示的区别名,比如[Unit]。注意,配置文件的区块名和字段名,都是大小写敏感的。

每个区块内部是一些等号连接的键值对。

[Section]
Directive1=value
Directive2=value
. . .

注意,键值对的等号两侧不能有空格。

(4)配置文件的区块

[Unit]区块通常是配置文件的第一个区块,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系。它的主要字段如下。

Description:简短描述
Documentation:文档地址
Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
Condition…:当前 Unit 运行必须满足的条件,否则不会运行
Assert…:当前 Unit 运行必须满足的条件,否则会报启动失败

[Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下:
WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
Alias:当前 Unit 可用于启动的别名
Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

[Service]区块用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块。它的主要字段如下:
Type:定义启动时的进程行为。它有以下几种值。
Type=simple:默认值,执行ExecStart指定的命令,启动主进程
Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
Type=dbus:当前服务通过D-Bus启动
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
Type=idle:若有其他任务执行完毕,当前服务才会运行
ExecStart:启动当前服务的命令
ExecStartPre:启动当前服务之前执行的命令
ExecStartPost:启动当前服务之后执行的命令
ExecReload:重启当前服务时执行的命令
ExecStop:停止当前服务时执行的命令
ExecStopPost:停止当其服务之后执行的命令
RestartSec:自动重启当前服务间隔的秒数
Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数
Environment:指定环境变量

Unit 配置文件的完整字段清单,请参考官方文档。

3.Unit 的依赖管理

很多服务之间是有依赖关系的,systemd 的一大亮点就是可以管理 unit 之间的依赖关系。我们可以通过下面的命令来查看 unit 间的依赖关系:

systemctl list-dependencies [unit] [–reverse],选项 --reverse 会反向追踪是谁在使用这个 unit。

下面让我们看看 graphical.target 的依赖关系:

[root@htlwk0001host ~]# systemctl list-dependencies multi-user.target
multi-user.target
● ├─aegis.service
● ├─aliyun.service
● ├─AssistDaemon.service

系统当前运行在 multi-user.target 下,它有一个长长的依赖列表(上面仅仅截取了部分项目),其中有一个依赖项目为 aliyun.service。下面我们使用 --reverse 选项查看 aliyun.service unit 被谁使用:

[root@htlwk0001host ~]# systemctl list-dependencies --reverse aliyun.service
aliyun.service
● └─multi-user.target
●   └─graphical.target

上面可以看到,aliyun.service 被 multi-user.target 使用,而 multi-user.target 被 graphical.target 使用,换句话说,multi-user.target 依赖于 aliyun.service,而 graphical.target 又依赖于 multi-user.target。

列出一个 Unit 的所有依赖:

$ systemctl list-dependencies nginx.service

有些依赖是 Target 类型,默认不会展开显示。如果要展开 Target,就需要使用 --all 参数:

$ systemctl list-dependencies --all nginx.service

(五)Systemd 的 Target 介绍

启动计算机的时候,需要启动大量的 Unit。如果每一次启动,都要一一写明本次启动需要哪些 Unit,显然非常不方便。Systemd 的解决方案就是 Target。

简单说,Target 就是一个 Unit 组,包含许多相关的 Unit 。启动某个 Target 的时候,Systemd 就会启动里面所有的 Unit。从这个意义上说,Target 这个概念类似于"状态点",启动某个 Target 就好比启动到某种状态。

传统的 init 启动模式里面,有 Run Level 的概念,跟 Target 的作用很类似。不同的是,Run Level 是互斥的,不可能多个 Run Level 同时启动,但是多个 Target 可以同时启动。

Systemd 使用 Target 取代了System V 的运行级的概念。在 Systemd 中,默认运行级别由 /etc/systemd/system/default.target 定义,这个文件本身是一个软连接,如果它指向 graphical.targer 那么默认的运行级别就是图形界面。

备注:Target 类型的 Unit 也可以理解为系统环境,当运行或切换个环境时往往会伴随着启动很多其他的 Unit 用以支持这个环境,最常见的环境就是字符界面(multi-user.target)和图形界面(graphical.target)

1.查看当前系统的所有 Target

[root@htlwk0001host ~]# systemctl list-unit-files --type=target
UNIT FILE                     STATE          
basic.target                  static         
bluetooth.target              static         
cloud-config.target           static         
cloud-init.target             enabled-runtime
cryptsetup-pre.target         static       

2.查看一个 Target 包含的所有 Unit

[root@htlwk0001host ~]# systemctl list-dependencies multi-user.target

3.查看启动时的默认 Target

[root@htlwk0001host ~]# systemctl get-default

4.设置启动时的默认 Target

[root@htlwk0001host ~]# sudo systemctl set-default multi-user.target

如果需要将系统默认运行的目标修改为“多用户,无图形”模式,可以直接用 ln 命令把多用户模式目标文件连接到 /etc/systemd/system/ 目录:

[root@htlwk0001host ~]# ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target

5.切换 Target

切换 Target 时,默认不关闭前一个 Target 启动的进程,

[root@htlwk0001host ~]# systemctl isolate multi-user.target

6.Target 与 传统 Run Level 的对应关系

Traditional runlevel      New target name     Symbolically linked to...

Runlevel 0           |    runlevel0.target -> poweroff.target     关闭系统
Runlevel 1           |    runlevel1.target -> rescue.target		  救援模式,单用户模式
Runlevel 2           |    runlevel2.target -> multi-user.target	  多用户,无图形模式,字符界面,标准模式,即命令行模式
Runlevel 3           |    runlevel3.target -> multi-user.target   多用户,无图形模式,字符界面,标准模式,即命令行模式
Runlevel 4           |    runlevel4.target -> multi-user.target   多用户,无图形模式,字符界面,标准模式,即命令行模式
Runlevel 5           |    runlevel5.target -> graphical.target    多用户,图形化模式
Runlevel 6           |    runlevel6.target -> reboot.target       重启系统

(六)Systemd 并行启动原理

在 Systemd 中,所有的服务都并发启动,比如 Avahi、D-Bus、livirtd、X11、HAL 可以同时启动。乍一看,这似乎有点儿问题,比如 Avahi 需要 syslog 的服务,Avahi 和 syslog 同时启动,假设 Avahi 的启动比较快,所以 syslog 还没有准备好,可是 Avahi 又需要记录日志,这岂不是会出现问题?

Systemd 的开发人员仔细研究了服务之间相互依赖的本质问题,发现所谓依赖可以分为三个具体的类型,而每一个类型实际上都可以通过相应的技术解除依赖关系。

并发启动原理之一:解决 socket 依赖

绝大多数的服务依赖是套接字依赖。比如服务 A 通过一个套接字端口 S1 提供自己的服务,其他的服务如果需要服务 A,则需要连接 S1。因此如果服务 A 尚未启动,S1 就不存在,其他的服务就会得到启动错误。所以传统地,人们需要先启动服务 A,等待它进入就绪状态,再启动其他需要它的服务。Systemd 认为,只要我们预先把 S1 建立好,那么其他所有的服务就可以同时启动而无需等待服务 A 来创建 S1 了。如果服务 A 尚未启动,那么其他进程向 S1 发送的服务请求实际上会被 Linux 操作系统缓存,其他进程会在这个请求的地方等待。一旦服务 A 启动就绪,就可以立即处理缓存的请求,一切都开始正常运行。

那么服务如何使用由 init 进程创建的套接字呢?

Linux 操作系统有一个特性,当进程调用 fork 或者 exec 创建子进程之后,所有在父进程中被打开的文件句柄 (file descriptor) 都被子进程所继承。套接字也是一种文件句柄,进程 A 可以创建一个套接字,此后当进程 A 调用 exec 启动一个新的子进程时,只要确保该套接字的 close_on_exec 标志位被清空,那么新的子进程就可以继承这个套接字。子进程看到的套接字和父进程创建的套接字是同一个系统套接字,就仿佛这个套接字是子进程自己创建的一样,没有任何区别。

这个特性以前被一个叫做 inetd 的系统服务所利用。Inetd 进程会负责监控一些常用套接字端口,比如 Telnet,当该端口有连接请求时,inetd 才启动 telnetd 进程,并把有连接的套接字传递给新的 telnetd 进程进行处理。这样,当系统没有 telnet 客户端连接时,就不需要启动 telnetd 进程。Inetd 可以代理很多的网络服务,这样就可以节约很多的系统负载和内存资源,只有当有真正的连接请求时才启动相应服务,并把套接字传递给相应的服务进程。

和 inetd 类似,systemd 是所有其他进程的父进程,它可以先建立所有需要的套接字,然后在调用 exec 的时候将该套接字传递给新的服务进程,而新进程直接使用该套接字进行服务即可。

并发启动原理之二:解决 D-Bus 依赖

D-Bus 是 desktop-bus 的简称,是一个低延迟、低开销、高可用性的进程间通信机制。它越来越多地用于应用程序之间通信,也用于应用程序和操作系统内核之间的通信。很多现代的服务进程都使用D-Bus 取代套接字作为进程间通信机制,对外提供服务。比如简化 Linux 网络配置的 NetworkManager 服务就使用 D-Bus 和其他的应用程序或者服务进行交互:邮件客户端软件 evolution 可以通过 D-Bus 从 NetworkManager 服务获取网络状态的改变,以便做出相应的处理。

D-Bus 支持所谓"bus activation"功能。如果服务 A 需要使用服务 B 的 D-Bus 服务,而服务 B 并没有运行,则 D-Bus 可以在服务 A 请求服务 B 的 D-Bus 时自动启动服务 B。而服务 A 发出的请求会被 D-Bus 缓存,服务 A 会等待服务 B 启动就绪。利用这个特性,依赖 D-Bus 的服务就可以实现并行启动。

并发启动原理之三:解决文件系统依赖

系统启动过程中,文件系统相关的活动是最耗时的,比如挂载文件系统,对文件系统进行磁盘检查(fsck),磁盘配额检查等都是非常耗时的操作。在等待这些工作完成的同时,系统处于空闲状态。那些想使用文件系统的服务似乎必须等待文件系统初始化完成才可以启动。但是 systemd 发现这种依赖也是可以避免的。

Systemd 参考了 autofs 的设计思路,使得依赖文件系统的服务和文件系统本身初始化两者可以并发工作。autofs 可以监测到某个文件系统挂载点真正被访问到的时候才触发挂载操作,这是通过内核 automounter 模块的支持而实现的。比如一个 open()系统调用作用在"/misc/cd/file1"的时候,/misc/cd 尚未执行挂载操作,此时 open()调用被挂起等待,Linux 内核通知 autofs,autofs 执行挂载。这时候,控制权返回给 open()系统调用,并正常打开文件。

Systemd 集成了 autofs 的实现,对于系统中的挂载点,比如/home,当系统启动的时候,systemd 为其创建一个临时的自动挂载点。在这个时刻/home 真正的挂载设备尚未启动好,真正的挂载操作还没有执行,文件系统检测也还没有完成。可是那些依赖该目录的进程已经可以并发启动,他们的 open()操作被内建在 systemd 中的 autofs 捕获,将该 open()调用挂起(可中断睡眠状态)。然后等待真正的挂载操作完成,文件系统检测也完成后,systemd 将该自动挂载点替换为真正的挂载点,并让 open()调用返回。由此,实现了那些依赖于文件系统的服务和文件系统本身同时并发启动。

当然对于"/"根目录的依赖实际上一定还是要串行执行,因为 systemd 自己也存放在/之下,必须等待系统根目录挂载检查好。

不过对于类似/home 等挂载点,这种并发可以提高系统的启动速度,尤其是当/home 是远程的 NFS 节点,或者是加密盘等,需要耗费较长的时间才可以准备就绪的情况下,因为并发启动,这段时间内,系统并不是完全无事可做,而是可以利用这段空余时间做更多的启动进程的事情,总的来说就缩短了系统启动时间。

(七)Systemd 配置使用

1.对于系统开发人员

开发人员需要了解 systemd 的更多细节。比如您打算开发一个新的系统服务,就必须了解如何让这个服务能够被 systemd 管理。这需要您注意以下这些要点:

(1)后台服务进程代码不需要执行两次派生来实现后台精灵进程,只需要实现服务本身的主循环即可。

(2)不要调用 setsid(),交给 systemd 处理。

(3)不再需要维护 pid 文件。

(4)Systemd 提供了日志功能,服务进程只需要输出到 stderr 即可,无需使用 syslog。

(5)处理信号 SIGTERM,这个信号的唯一正确作用就是停止当前服务,不要做其他的事情。

(6)SIGHUP 信号的作用是重启服务。

(7)需要套接字的服务,不要自己创建套接字,让 systemd 传入套接字。

(8)使用 sd_notify()函数通知 systemd 服务自己的状态改变。一般地,当服务初始化结束,进入服务就绪状态时,可以调用它。

对于开发者来说,工作量最大的部分应该是编写配置单元文件,定义所需要的单元。

举例来说,开发人员开发了一个新的服务程序,比如 httpd,就需要为其编写一个配置单元文件以便该服务可以被 systemd 管理,类似 UpStart 的工作配置文件。在该文件中定义服务启动的命令行语法,以及和其他服务的依赖关系等。

此外我们之前已经了解到,systemd 的功能繁多,不仅用来管理服务,还可以管理挂载点,定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。我在这里给出几个配置单元文件的例子。

服务配置单元文件以 .service 为文件名后缀,下面是 SSH 服务的配置单元文件:

[root@htlwk0001host ~]# cat /etc/system/system/sshd.service
  [Unit]
  Description=OpenSSH server daemon
  [Service]
  EnvironmentFile=/etc/sysconfig/sshd
  ExecStartPre=/usr/sbin/sshd-keygen
  ExecStart=/usrsbin/sshd –D $OPTIONS
  ExecReload=/bin/kill –HUP $MAINPID
  KillMode=process
  Restart=on-failure
  RestartSec=42s
  [Install]
  WantedBy=multi-user.target

文件分为三个小节:
第一部分是[Unit],这里仅仅有一个描述信息。
第二部分是[Service] ,对服务进行相关的定义。其中,ExecStartPre 定义启动服务之前应该运行的命令;ExecStart 定义启动服务的具体命令行语法。
第三部分是[Install],WangtedBy 表明这个服务是在多用户模式下所需要的。

那我们再就来看下 multi-user.target:

  [root@htlwk0001host ~]# cat multi-user.target
  [Unit]
  Description=Multi-User System
  Documentation=man.systemd.special(7)
  Requires=basic.target
  Conflicts=rescue.service rescure.target
  After=basic.target rescue.service rescue.target
  AllowIsolate=yes
  [Install]
  Alias=default.target

第一部分中的 Requires 定义表明 multi-user.target 启动的时候 basic.target 也必须被启动;另外 basic.target 停止的时候,multi-user.target 也必须停止。如果您接着查看 basic.target 文件,会发现它又指定了 sysinit.target 等其他的单元必须随之启动。同样 sysinit.target 也会包含其他的单元。采用这样的层层链接的结构,最终所有需要支持多用户模式的组件服务都会被初始化启动好。

在[Install]小节中有 Alias 定义,即定义本单元的别名,这样在运行 systemctl 的时候就可以使用这个别名来引用本单元。这里的别名是 default.target,比 multi-user.target 要简单一些。

此外在/etc/systemd/system 目录下还可以看到诸如*.wants 的目录,放在该目录下的配置单元文件等同于在[Unit]小节中的 wants 关键字,即本单元启动时,还需要启动这些单元。比如您可以简单地把您自己写的 foo.service 文件放入 multi-user.target.wants 目录下,这样每次都会被默认启动了。

最后,让我们来看看 sys-kernel-debug.mout 文件,这个文件定义了一个文件挂载点:

[root@htlwk0001host ~]# cat sys-kernel-debug.mount
[Unit]
Description=Debug File Syste
DefaultDependencies=no
ConditionPathExists=/sys/kernel/debug
Before=sysinit.target
[Mount]
What=debugfs
Where=/sys/kernel/debug
Type=debugfs

这个配置单元文件定义了一个挂载点。挂载配置单元文件有一个[Mount]配置小节,里面配置了 What,Where 和 Type 三个数据项。这都是挂载命令所必须的,例子中的配置等同于下面这个挂载命令:

[root@htlwk0001host ~]# mount –t debugfs /sys/kernel/debug debugfs

配置单元文件的编写需要很多的学习,必须参考 systemd 附带的 man 等文档进行深入学习。希望通过上面几个小例子,大家已经了解配置单元文件的作用和一般写法了。

2.对于系统管理员

作为系统管理员必须非常熟悉系统服务和 init 系统的管理,否则请自动辞职。比如 service、chkconfig 以及 telinit 命令的使用。而使用 Systemd 作为初始化系统的 Linux 系统则是使用命令 systemctl 来管理和控制系统服务,systemctl 和旧命令存在较大的语法差别,所以作为系统管理员必须牢记其中的差别,能够做到在新旧系统灵活切换。

二、使用命令 systemctl 管理系统服务

(一)命令介绍

我们知道使用 SysV 或者 UpStart 初始化的 Linux 发行版( 例如:Red Hat 旗下的 Centos 7.x 之前的 Linux 系统)都是使用命令 servicechkconfig 来管理系统服务,而使用 Systemd 作为 Init System 的Linux 发行版(Centos 7.x 之后的 Linux 系统)则是使用新的管理命令 systemctl 来启动、停止、重启、禁用、查看系统服务,该命令集成了命令 servicechkconfigsetupinit 的大部分功能于一身。

systemctl 命令有两大类功能:

  1. 控制 systemd 系统
  2. 管理系统上运行的服务

备注:为了向前兼容,旧命令 service 在新版本的 Linux 中仍然可以使用,只是会被重定向到新的 systemctl 工具

(二)命令选项

systemctl 提供了一组子命令(命令选项)来管理单个的 unit,其命令格式为: systemctl <command> <unit>。unit 是指服务单元,就是指服务进程。命令选项如下:

选项说明
start立刻启动后面接的 unit
stop立刻关闭后面接的 unit
restart立刻关闭后启动后面接的 unit,亦即执行 stop 再 start 的意思
reload不关闭 unit 的情况下,重新载入配置文件,让设置生效
enable设置下次开机时,后面接的 unit 会被启动
disable设置下次开机时,后面接的 unit 不会被启动
status目前后面接的这个 unit 的状态,会列出有没有正在执行、开机时是否启动等信息
is-active目前有没有正在运行中
is-enable开机时有没有默认启动这个 unit
kill向运行 unit 的进程发送终止信号
show列出 unit 的配置
mask注销 unit,注销后你就无法启动这个 unit 了
unmask取消对 unit 的注销
list-dependencies [unit] [–reverse]选项 --reverse 会反向追踪是谁在使用这个 unit
list-units列出当前所有已启动的服务,如果添加 -all 选项会同时列出没有启动的服务,添加 --type 可以过滤某个类型的 unit
list-unit-files根据 /lib/systemd/system/ 目录内的文件列出所有的 uni
get-default取得目前的操作模式(target)
set-default设置后面接的 target 成为默认的操作模式
isolate切换到后面接的模式
poweroff系统关机,systemctl poweroff 关机(相当于 systemctl isolate poweroff.target)
reboot重启系统
suspend进入暂停模式,将系统数据写入内存,同时将大部分硬件关闭,等待唤醒(相当于Windows下的睡眠)
hibernate进入休眠模式,将系统数据写入硬盘,然后关机
rescue强制进入救援模式
emergency强制进入紧急救援模式,比救援模式更强更彻底

(三)Systemd 命令和 SysV init 命令的对比

Systemd 命令SysV init 命令说明
systemctl start foo.serviceservice foo start用来启动一个服务 (并不会重启现有的)

(四)命令示例

1.重启 restart

使用选项 restart,如果服务在运行中,它将重启服务;如果服务不在运行中,它将会启动服务

[root@htlwk0001host ~]# systemctl restart httpd.service

2.纯重启 try-restart

使用选项 try-restart,它会在服务已经在运行中的时候重启服务

[root@htlwk0001host ~]# systemctl try-restart httpd.service

3.重新加载 reload

使用选项 reload,它会重新加载配置文件

[root@htlwk0001host ~]# systemctl reload httpd.service

4.启动 start

启动服务

[root@htlwk0001host ~]# systemctl start httpd.service

5.停止 stop

停止服务

[root@htlwk0001host ~]# systemctl stop httpd.service

6.查看服务状态 status

查看服务的状态,我们看看服务 mysqld 的基本信息有些什么:

[root@htlwk0001host ~]# systemctl status mysqld.service
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2021-04-23 16:11:01 CST; 1 weeks 1 days ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 1069004 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 1068982 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 1069006 (mysqld)
    Tasks: 55 (limit: 23070)
   Memory: 344.2M
   CGroup: /system.slice/mysqld.service
           └─1069006 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

4月 23 16:10:59 htlwk0001host systemd[1]: Starting MySQL Server...
4月 23 16:11:01 htlwk0001host systemd[1]: Started MySQL Server.

(1)解读服务状态信息

第一行是对 mysqld 的基本描述。
第二行是描述操作系统启动时会不会启动这个服务,enabled 表示开机时启动,disabled 表示开机时不启动。而启动该服务的配置文件路径为:/usr/lib/systemd/system/mysqld.service。
第三行是描述服务当前的状态,active (running) 表示服务正在运行中。如果是 inactive (dead) 则表示服务当前没有运行。后面则是服务的启动时间。
第四行提供了关于服务的在线文档地址。
第七行显示出该服务的主进程的 ID。
第八行显示了该服务关联的任务数量。
第九行显示了该服务占用的内存大小。
最后两行是输出的日志信息。

(2)关于服务的启动状态

关于 unit 的启动状态,除了 enable 和 disable 之外还有:

  • static:这个 unit 不可以自己启动,不过可能会被其它的 enabled 的服务来唤醒。
  • mask:这个 unit 无论如何都无法被启动!因为已经被强制注销。可通过 systemctl unmask 改回原来的状态。

(3)关于服务的运行状态

关于 unit 的运行状态 Active,除了 active 和 inactive 之外还有:

  • active (exited):仅执行一次就正常结束的服务,举例来说,开机或者是挂载时才会进行一次的 quotaon 功能,就是这种模式。Quotaon 不需要一直执行,只在执行一次之后,就交给文件系统去自行处理。通常用 bash shell 写的小型服务,大多是属于这种类型。
  • active (waiting):正在执行当中,不过还再等待其他的事件才能继续处理。举例来说,打印的相关服务就是这种状态。

7.开机启动 enable

使用选项 enable 设置开机启动某个服务

[root@htlwk0001host ~]# systemctl enable httpd.service

8.取消开机启动 disable

使用选项 disable 设置开机禁用某个服务,就是取消某个服务的开机启动

[root@htlwk0001host ~]# systemctl disable httpd.service

9.查看是否开机启动 is-enabled

查看某个服务是否开机启动

[root@htlwk0001host ~]# systemctl is-enabled httpd.service

10.查看启动失败的服务 -failed

查看启动失败的服务

[root@htlwk0001host ~]# systemctl –failed

11.查看进程是不是在运行中 is-active

查看进程目前是不是正在运行中

[root@htlwk0001host ~]# systemctl is-active sshd.service

12.查看系统中所有已经启动的服务

输入命令 systemctl,相当于 输入 systemctl list-units

[root@htlwk0001host ~]# systemctl
UNIT                                                                        LOAD   ACTIVE SUB       DESCRIPTION                                                                  
proc-sys-fs-binfmt_misc.automount                                           loaded active running   Arbitrary Executable File Formats File System Automount Point                
sys-devices-pci0000:00-0000:00:03.0-virtio0-virtio\x2dports-vport0p1.device loaded active plugged   /sys/devices/pci0000:00/0000:00:03.0/virtio0/virtio-ports/vport0p1           
sys-devices-pci0000:00-0000:00:04.0-virtio1-block-vda-vda1.device           loaded active plugged   /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1                  
sys-devices-pci0000:00-0000:00:04.0-virtio1-block-vda.device                loaded active plugged   /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda                       
sys-devices-pci0000:00-0000:00:05.0-virtio2-net-eth0.device                 loaded active plugged   Virtio network device                                                        
sys-devices-platform-serial8250-tty-ttyS1.device                            loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS1                                   
sys-devices-platform-serial8250-tty-ttyS2.device                            loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS2   

UNIT:项目的名称,包括各个 unit 的类别(看扩展名)。
LOAD:开机时 unit 的配置是否被加载。
ACTIVE:服务的运行主状态,active 表示“活着”,inactive 表示死了
SUB:服务的运行子状态,例如:running,表示服务不仅“活着”,还正在“忙碌”呢!
DESCRIPTION:描述信息

13.根据目录 /lib/systemd/system/ 内的 service 文件查看系统的服务单元

[root@htlwk0001host ~]# systemctl list-unit-files;
UNIT FILE                                  STATE          
proc-sys-fs-binfmt_misc.automount          static         
-.mount                                    generated      
dev-hugepages.mount                        static         
dev-mqueue.mount                           static         
proc-sys-fs-binfmt_misc.mount              static         
sys-fs-fuse-connections.mount              static         
sys-kernel-config.mount                    static         
sys-kernel-debug.mount                     static         
tmp.mount                                  disabled       

STATE 就是我们前面介绍的服务的启动状态。

14.只看服务类型的 unit

[root@htlwk0001host ~]# systemctl list-units --type=service
UNIT                               LOAD   ACTIVE SUB     DESCRIPTION                                                                  
aegis.service                      loaded active running LSB: aegis update.                                                           
aliyun.service                     loaded active running 阿里云助手                                                              
AssistDaemon.service               loaded active running AssistDaemon                                                                 
atd.service                        loaded active running Job spooling tools                                                           
auditd.service                     loaded active running Security Auditing Service       

15.查看加载失败的 unit

[root@htlwk0001host ~]# systemctl --failed
0 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

16.管理系统的操作环境(target unit)

通过指定 --type=target 就可以用 systemctl list-units 命令查看系统中默认有多少种 target:

[root@htlwk0001host ~]# systemctl list-units --type=target -all
  UNIT                      LOAD      ACTIVE   SUB    DESCRIPTION                  
  basic.target              loaded    active   active Basic System                 
  cloud-config.target       loaded    active   active Cloud-config availability    
  cloud-init.target         loaded    active   active Cloud-init target            
  cryptsetup.target         loaded    active   active Local Encrypted Volumes      
  emergency.target          loaded    inactive dead   Emergency Mode               
  getty-pre.target          loaded    inactive dead   Login Prompts (Pre)          
  getty.target              loaded    active   active Login Prompts                
  graphical.target          loaded    inactive dead   Graphical Interface          
  initrd-fs.target          loaded    inactive dead   Initrd File Systems          
  initrd-root-device.target loaded    inactive dead   Initrd Root Device           
  initrd-root-fs.target     loaded    inactive dead   Initrd Root File System      
  initrd-switch-root.target loaded    inactive dead   Switch Root                  
  initrd.target             loaded    inactive dead   Initrd Default Target        
  local-fs-pre.target       loaded    active   active Local File Systems (Pre)     
  local-fs.target           loaded    active   active Local File Systems           
  multi-user.target         loaded    active   active Multi-User System            
  network-online.target     loaded    active   active Network is Online            
  network-pre.target        loaded    active   active Network (Pre)                
  network.target            loaded    active   active Network                      
  nss-lookup.target         loaded    active   active Host and Network Name Lookups
  nss-user-lookup.target    loaded    active   active User and Group Name Lookups  
  paths.target              loaded    active   active Paths                        
  remote-fs-pre.target      loaded    inactive dead   Remote File Systems (Pre)    
  remote-fs.target          loaded    active   active Remote File Systems          
  rescue.target             loaded    inactive dead   Rescue Mode                  
  shutdown.target           loaded    inactive dead   Shutdown                     
  slices.target             loaded    active   active Slices                       
  sockets.target            loaded    active   active Sockets                      
  sshd-keygen.target        loaded    active   active sshd-keygen.target           
  swap.target               loaded    active   active Swap                         
  sysinit.target            loaded    active   active System Initialization        
  syslog.target             not-found inactive dead   syslog.target                
  time-sync.target          loaded    inactive dead   System Time Synchronized     
  timers.target             loaded    active   active Timers                       
  umount.target             loaded    inactive dead   Unmount All Filesystems      

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

35 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.

我的服务器主机居然有 34 个 target,在此仅介绍几个常用的 target:

  • graphical.target:就是文字界面再加上图形界面,这个 target 已经包含了下面的 multi-user.target
  • multi-user.target:纯文本模式
  • rescue.target:在无法使用 root 登陆的情况下,systemd 在开机时会多加一个额外的临时系统,与你原本的系统无关。这时你可以取得 root 的权限来维护你的系统
  • emergency.target:紧急处理系统的错误,在无法使用 rescue.target 时,可以尝试使用这种模式
  • shutdown.target:就是执行关机
  • getty.target:可以设置 tty 的配置

正常的模式是 multi-user.target 和 graphical.target 两个,救援方面的模式主要是 rescue.target 以及更严重的 emergency.target。如果要修改可提供登陆的 tty 数量,则修改 getty.target。

(1)查看系统目前的操作模式(target)

[root@htlwk0001host ~]# systemctl get-default;
multi-user.target

(2)设置系统默认的操作模式

[root@htlwk0001host ~]# systemctl set-default multi-user.target

(3)切换操作模式

可以在不重新启动的情况下切换不同的 target,比如从图形界面切换到纯文本的模式(即命令行模式):

[root@htlwk0001host ~]# systemctl isolate multi-user.target

切换到图形模式:

[root@htlwk0001host ~]# systemctl isolate runlevel5.target # 运行等级5

或者

[root@htlwk0001host ~]# systemctl isolate graphical.target

17.让系统进入暂停模式

[root@htlwk0001host ~]# systemctl suspend

暂停模式会将系统的状态保存到内存中,然后关闭掉大部分的系统硬件,当然,并没有实际关机。当用户按下唤醒机器的按钮,系统数据会从内存中回复,然后重新驱动被大部分关闭的硬件,所以唤醒系统的速度比较快。

18.让系统进入休眠模式

[root@htlwk0001host ~]# systemctl hibernate

休眠模式则是将系统状态保存到硬盘当中,保存完毕后,将计算机关机。当用户尝试唤醒系统时,系统会开始正常运行,然后将保存在硬盘中的系统状态恢复回来。因为数据需要从硬盘读取,因此唤醒的速度比较慢(如果你使用的是 SSD 磁盘,唤醒的速度也是非常快的)。

19.强制系统进入救援模式

[root@htlwk0001host ~]# systemctl rescue

20.强制系统进入紧急救援模式

[root@htlwk0001host ~]# systemctl emergency 

22.重新加载 systemd 程序的配置文件

[root@htlwk0001host ~]# systemctl daemon-reload

(1)新添加 unit 配置文件时需要执行 systemctl daemon-reload
(2)有 unit 的配置文件发生变化时也需要执行 systemctl daemon-reload

daemon-reload 命令会做很多的事情,其中之一是重新生成依赖树(也就是 unit 之间的依赖关系),所以当你修改了 unit 配置文件中的依赖关系后如果不执行 daemon-reload 命令是不会生效的。

23.杀死服务

[root@htlwk0001host ~]# systemctl kill mysqld.service

24.管理系统挂载点的命令

(1)挂载

[root@htlwk0001host ~]# systemctl start tmp.mount

(2)卸载

[root@htlwk0001host ~]# systemctl stop tmp.mount

(3)重新挂载

[root@htlwk0001host ~]# systemctl restart tmp.mount

(4)重新加载挂载点

[root@htlwk0001host ~]# systemctl reload tmp.mount

(5)查看挂载点状态

[root@htlwk0001host ~]# systemctl status tmp.mount

25.查看 systemd 的版本

[root@htlwk0001host ~]# systemctl --version
systemd 239
+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy

26.查看系统启动耗时

[root@htlwk0001host ~]# systemd-analyze
Startup finished in 659ms (kernel) + 5.114s (initrd) + 10.495s (userspace) = 16.269s
multi-user.target reached after 9.540s in userspace

27.查看每个进程在引导时花费的时间

查看每个服务的启动耗时:

[root@htlwk0001host ~]# systemd-analyze blame
          5.405s cloud-init-local.service
          2.875s cloud-init.service
          2.631s sshd-keygen@rsa.service
          1.707s dracut-pre-pivot.service
          1.501s mysqld.service
          1.095s aegis.service
           954ms systemd-logind.service

28.查看指定服务的关键链

显示指定服务的瀑布状的启动过程流:

[root@htlwk0001host ~]# systemd-analyze critical-chain httpd.service
The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.
httpd.service +142ms
└─network.target @11.168s
└─network.service @9.456s +1.712s
└─NetworkManager.service @8.858s +596ms
└─firewalld.service @4.931s +3.926s
└─basic.target @4.916s
└─sockets.target @4.916s
└─dbus.socket @4.916s
└─sysinit.target @4.905s
└─systemd-update-utmp.service @4.864s +39ms
└─auditd.service @4.563s +301ms
└─systemd-tmpfiles-setup.service @4.485s +69ms
└─rhel-import-state.service @4.342s +142ms
└─local-fs.target @4.324s
└─boot.mount @4.286s +31ms
└─systemd-fsck@dev-disk-by\x2duuid-79f594ad\x2da332\x2d4730\x2dbb5f\x2d85d196080964.service @4.092s +149ms
└─dev-disk-by\x2duuid-79f594ad\x2da332\x2d4730\x2dbb5f\x2d85d196080964.device @4.092s

显示瀑布状的启动过程流:

[root@htlwk0001host ~]# systemd-analyze critical-chain

29.获取服务的依赖项列表

[root@htlwk0001host ~]# systemctl list-dependencies httpd.service
httpd.service
├─system.slice
└─basic.target
├─firewalld.service
├─microcode.service
├─rhel-autorelabel-mark.service
├─rhel-autorelabel.service
├─rhel-configure.service
├─rhel-dmesg.service
├─rhel-loadmodules.service
├─paths.target
├─slices.target
│ ├─-.slice
│ └─system.slice
├─sockets.target
│ ├─dbus.socket
....

30.按层次列出控制组

[root@htlwk0001host ~]# systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 23
├─user.slice
│ └─user-0.slice
│   └─session-1.scope
│     ├─2498 sshd: root@pts/0    
│     ├─2500 -bash
│     ├─4521 systemd-cgls
│     └─4522 systemd-cgls
└─system.slice
├─httpd.service
│ ├─4440 /usr/sbin/httpd -DFOREGROUND
│ ├─4442 /usr/sbin/httpd -DFOREGROUND
│ ├─4443 /usr/sbin/httpd -DFOREGROUND
│ ├─4444 /usr/sbin/httpd -DFOREGROUND
│ ├─4445 /usr/sbin/httpd -DFOREGROUND
│ └─4446 /usr/sbin/httpd -DFOREGROUND
├─polkit.service
│ └─721 /usr/lib/polkit-1/polkitd --no-debug
....

31.根据CPU,内存,输入和输出列出控制组

[root@htlwk0001host ~]# systemd-cgtop
Path                                                              Tasks   %CPU   Memory  Input/s Output/s
/                                                                    83    1.0   437.8M        -        -
/system.slice                                                         -    0.1        -        -        -
/system.slice/mariadb.service                                         2    0.1        -        -        -
/system.slice/tuned.service                                           1    0.0        -        -        -
/system.slice/httpd.service                                           6    0.0        -        -        -
/system.slice/NetworkManager.service                                  1      -        -        -        -
/system.slice/atop.service                                            1      -        -        -        -
/system.slice/atopacct.service                                        1      -        -        -        -
/system.slice/auditd.service                                          1      -        -        -        -
/system.slice/crond.service                                           1      -        -        -        -
/system.slice/dbus.service                                            1      -        -        -        -
/system.slice/firewalld.service                                       1      -        -        -        -
/system.slice/lvm2-lvmetad.service                                    1      -        -        -        -
/system.slice/polkit.service                                          1      -        -        -        -
/system.slice/postfix.service                                         3      -        -        -        -
/system.slice/rsyslog.service                                         1      -        -        -        -
/system.slice/system-getty.slice/getty@tty1.service                   1      -        -        -        -
/system.slice/systemd-journald.service                                1      -        -        -        -
/system.slice/systemd-logind.service                                  1      -        -        -        -
/system.slice/systemd-udevd.service                                   1      -        -        -        -
/system.slice/webmin.service                                          1      -        -        -        -
/user.slice/user-0.slice/session-1.scope                              3      -        -        -        -

32.查看指定类型的 unit

[root@htlwk0001host ~]# systemctl -t target
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION                  
basic.target           loaded active active Basic System                 
cloud-config.target    loaded active active Cloud-config availability    
cloud-init.target      loaded active active Cloud-init target            
cryptsetup.target      loaded active active Local Encrypted Volumes      
getty.target           loaded active active Login Prompts                
local-fs-pre.target    loaded active active Local File Systems (Pre)     
local-fs.target        loaded active active Local File Systems           
multi-user.target      loaded active active Multi-User System            
network-online.target  loaded active active Network is Online            
network-pre.target     loaded active active Network (Pre)                
network.target         loaded active active Network                      
nss-lookup.target      loaded active active Host and Network Name Lookups
nss-user-lookup.target loaded active active User and Group Name Lookups  
paths.target           loaded active active Paths                        
remote-fs.target       loaded active active Remote File Systems          
slices.target          loaded active active Slices                       
sockets.target         loaded active active Sockets                      
sshd-keygen.target     loaded active active sshd-keygen.target           
swap.target            loaded active active Swap                         
sysinit.target         loaded active active System Initialization        
timers.target          loaded active active Timers                       

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

21 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
[root@htlwk0001host ~]# systemctl --type target
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION                  
basic.target           loaded active active Basic System                 
cloud-config.target    loaded active active Cloud-config availability    
cloud-init.target      loaded active active Cloud-init target            
cryptsetup.target      loaded active active Local Encrypted Volumes      
getty.target           loaded active active Login Prompts                
local-fs-pre.target    loaded active active Local File Systems (Pre)     
local-fs.target        loaded active active Local File Systems           
multi-user.target      loaded active active Multi-User System            
network-online.target  loaded active active Network is Online            
network-pre.target     loaded active active Network (Pre)                
network.target         loaded active active Network                      
nss-lookup.target      loaded active active Host and Network Name Lookups
nss-user-lookup.target loaded active active User and Group Name Lookups  
paths.target           loaded active active Paths                        
remote-fs.target       loaded active active Remote File Systems          
slices.target          loaded active active Slices                       
sockets.target         loaded active active Sockets                      
sshd-keygen.target     loaded active active sshd-keygen.target           
swap.target            loaded active active Swap                         
sysinit.target         loaded active active System Initialization        
timers.target          loaded active active Timers                       

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

21 loaded units listed. Pass --all to see loaded but inactive units
[root@htlwk0001host ~]# systemctl --type=target
UNIT                   LOAD   ACTIVE SUB    DESCRIPTION                  
basic.target           loaded active active Basic System                 
cloud-config.target    loaded active active Cloud-config availability    
cloud-init.target      loaded active active Cloud-init target            
cryptsetup.target      loaded active active Local Encrypted Volumes      
getty.target           loaded active active Login Prompts                
local-fs-pre.target    loaded active active Local File Systems (Pre)     
local-fs.target        loaded active active Local File Systems           
multi-user.target      loaded active active Multi-User System            
network-online.target  loaded active active Network is Online            
network-pre.target     loaded active active Network (Pre)                
network.target         loaded active active Network                      
nss-lookup.target      loaded active active Host and Network Name Lookups
nss-user-lookup.target loaded active active User and Group Name Lookups  
paths.target           loaded active active Paths                        
remote-fs.target       loaded active active Remote File Systems          
slices.target          loaded active active Slices                       
sockets.target         loaded active active Sockets                      
sshd-keygen.target     loaded active active sshd-keygen.target           
swap.target            loaded active active Swap                         
sysinit.target         loaded active active System Initialization        
timers.target          loaded active active Timers                       

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

21 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

33.列出所有没有运行的 Unit

$ systemctl list-units --all --state=inactive

34.查看系统状态

[root@htlwk0001host ~]# systemctl status
● htlwk0001host
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: Sun 2020-08-23 18:02:02 CST; 8 months 10 days ago
   CGroup: /
           ├─user.slice
           │ └─user-0.slice
           │   ├─session-10.scope
           │   │ ├─ 26556 nginx: master process nginx
           │   │ ├─414774 nginx: worker process
           │   │ └─414775 nginx: worker process
           │   ├─session-575.scope
           │   │ ├─1111169 sshd: root [priv]
           │   │ ├─1111171 sshd: root@pts/0

35.显示远程主机的某个 Unit 的状态

$ systemctl -H root@rhel7.example.com status httpd.service

36.显示某个 Unit 是否处于启动失败状态

$ systemctl is-failed application.service

37.重载所有修改过的配置文件

$ sudo systemctl daemon-reload

38.显示某个 Unit 的指定属性的值

$ systemctl show -p CPUShares httpd.service

39.设置某个 Unit 的指定属性

$ sudo systemctl set-property httpd.service CPUShares=500

(六)systemctl 与 旧命令的对比

任务旧指令systemctl 指令
设置某服务开机时启动chkconfig --level 3 httpd onsystemctl enable httpd.service
设置某服务开机时不启动chkconfig --level 3 httpd offsystemctl disable httpd.service
检查服务状态service httpd statussystemctl status httpd.service
显示所有已启动的服务chkconfig --listsystemctl list-units --type=service
启动某服务service httpd startsystemctl start httpd.service
停止某服务service httpd stopsystemctl stop httpd.service
重启某服务service httpd restartsystemctl restart httpd.service


这篇关于Linux 系统服务管理器 Systemd 及命令 systemctl 的详细介绍的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程