手把手教会你使用 Systemd-Analyze 优化系统启动速度

Posted by Mike on 2020-05-13

systemd-analyze 简介

systemd-analyze 是 Linux 自带的分析系统启动性能的工具。

systemd-analyze 可使用的命令:

1
2
3
4
5
6
7
8
9
10
11
12
systemd-analyze [OPTIONS…] [time]
systemd-analyze [OPTIONS…] blame
systemd-analyze [OPTIONS…] critical-chain [UNIT…]
systemd-analyze [OPTIONS…] plot [> file.svg]
systemd-analyze [OPTIONS…] dot [PATTERN…] [> file.dot]
systemd-analyze [OPTIONS…] dump
systemd-analyze [OPTIONS…] set-log-level LEVEL
systemd-analyze [OPTIONS…] set-log-target TARGET
systemd-analyze [OPTIONS…] get-log-level
systemd-analyze [OPTIONS…] get-log-target
systemd-analyze [OPTIONS…] syscall-filter [SET…]
systemd-analyze [OPTIONS…] verify [FILES…]

systemd-analyze命令具体含义:

  • systemd-analyze 可以显示系统启动过程中的性能统计数据、 获取 systemd 系统管理器的状态与跟踪信息、 校验单元文件的正确性。

  • systemd-analyze time 可以显示如下时间: (1)在启动第一个用户态进程(init)之前,内核运行了多长时间; (2)在切换进入实际的根文件系统之前,initrd(initial RAM disk)运行了多长时间; (3)进入实际的根文件系统之后,用户空间启动完成花了多长时间。 注意,上述时间只是简单的计算了系统启动过程中到达不同标记点的时间, 并没有计入各单元实际启动完成所花费的时间以及磁盘空闲的时间。

  • systemd-analyze blame 按照每个单元花费的启动时间从多到少的顺序,列出所有当前正处于活动(active)状态的单元。 这些信息有助于用户优化系统启动速度。 不过需要注意的是,这些信息也可能具有误导性, 因为花费较长时间启动的单元,有可能只是在等待另一个依赖单元完成启动。

  • systemd-analyze critical-chain [UNIT…] 为指定的单元(省略参数表示默认启动目标单元)以树状形式显示时间关键链(time-critical chain)。 “@”后面的时刻表示该单元的启动时刻; “+”后面的时长表示该单元总计花了多长时间才完成启动。 不过需要注意的是, 这些信息也可能具有误导性, 因为花费较长时间启动的单元, 有可能只是在等待另一个依赖单元完成启动。

  • systemd-analyze plot 输出一个 SVG 图像,详细显示每个单元的启动时刻, 并高亮显示每个单元总计花了多长时间才完成启动。

  • systemd-analyze dot 按照 GraphViz dot(1) 格式输出单元间的依赖关系图。 在实践中,通常使用 systemd-analyze dot | dot -Tsvg > systemd.svg命令来最终生成描述单元间依赖关系的 SVG 图像。 除非使用了 –order–require 选项限定仅显示特定类型的依赖关系, 否则将会显示所有的依赖关系。如果指定了至少一个 PATTERN 参数(例如 *.target 这样的 shell 匹配模式), 那么将会仅显示所有匹配这些模式的单元的直接依赖关系。

  • systemd-analyze dump 按照人类易读的格式输出全部单元的状态(一般都有几千数万行)。 因为它的输出格式经常在未通知的情况下发生变化, 所以切勿将此输出用于程序分析。

  • systemd-analyze set-log-level LEVEL 将 systemd 守护进程的日志等级更改为 LEVEL (可使用的值参见 systemd(1) 的 –log-level= 选项)

  • systemd-analyze set-log-target TARGET 将 systemd 守护进程的日志目标更改为 TARGET (可使用的值参见 systemd(1) 的 –log-target= 选项)

  • systemd-analyze get-log-level 打印出 systemd 守护进程当前的日志等级。

  • systemd-analyze get-log-target 打印出 systemd 守护进程当前的日志目标。

  • systemd-analyze syscall-filter [SET…] 如果指定了至少一个 SET 参数,那么仅显示指定的集合所包含的系统调用列表; 否则显示全部系统调用集合的详情。注意,必须在 SET 参数中包含 “@” 前缀。

  • systemd-analyze verify 校验指定的单元文件以及被指定的单元文件引用的其他单元文件的正确性,并显示发现的错误。 FILES 参数可以是单元文件的精确路径(带有上级目录),也可以仅仅是单元文件的名称(没有目录前缀)。 对于那些仅给出了文件名(没有目录前缀)的单元,将会优先在其他已经给出精确路径的单元文件的所在目录中搜索, 如果没有找到,将会继续在常规的单元目录中搜索(详见 unit(5) 手册)。 可以使用 $SYSTEMD_UNIT_PATH 环境变量来更改默认的单元搜索目录。

  • 如果没指定任何命令,那么等价于使用 systemd-analyze time 命令。

systemd-analyze 实战

1
2
3
➜~ systemd-analyze
Startup finished in 3.220s (kernel) + 23.420s (userspace) = 26.641s
graphical.target reached after 23.111s in userspace

可以看到开机用了 23 秒以上。接下来查询下这锅应该谁背:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
➜~ systemd-analyze blame
21.594s NetworkManager-wait-online.service
680ms systemd-logind.service
587ms lvm2-monitor.service
570ms lightdm.service
534ms dev-sdc2.device
371ms upower.service
309ms tlp.service
292ms systemd-timesyncd.service
260ms systemd-udevd.service
252ms ModemManager.service
217ms systemd-journald.service
131ms systemd-journal-flush.service
121ms boot-efi.mount
117ms avahi-daemon.service
115ms bluetooth.service
111ms polkit.service
111ms NetworkManager.service
110ms udisks2.service
102ms systemd-modules-load.service

可以看到 NetworkManager-wait-online.service 耗时 最长,花了 21 秒。这里的记时有可能是等待其他服务器启动的,再来看看其关联服务的启动时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
➜ ~ systemd-analyze critical-chain NetworkManager-wait-online.service
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.

NetworkManager-wait-online.service +21.594s
└─NetworkManager.service @1.398s +111ms
└─dbus.service @1.390s
└─basic.target @1.389s
└─sockets.target @1.389s
└─dbus.socket @1.389s
└─sysinit.target @1.384s
└─systemd-backlight@backlight:intel_backlight.service @1.313s +71ms
└─system-systemd\x2dbacklight.slice @1.312s
└─system.slice @207ms
└─-.slice @207ms

可这一看到这里它在等待其他的服务,但是也没有花 21 秒怎么多。

发现了影响启动的服务,最简单的方式是禁用此服务:

1
➜ ~ sudo systemctl disable NetworkManager-wait-online.service

另一种解决办法就是编辑 /lib/systemd/system/NetworkManager-wait-online.service 文件,将文件中的超时时间由 30 改为 10。

1
[Service] Type=oneshot ExecStart=/usr/bin/nm-online -s -q --timeout=30

另外,我们来看下还有哪些开机启动的服务可被优化:

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
➜ ~ systemctl list-unit-files --type=service | grep enabled
autovt@.service enabled
avahi-daemon.service enabled
bluetooth.service enabled
bumblebeed.service enabled
cronie.service enabled
dbus-org.bluez.service enabled
dbus-org.freedesktop.Avahi.service enabled
dbus-org.freedesktop.ModemManager1.service enabled
dbus-org.freedesktop.NetworkManager.service enabled
dbus-org.freedesktop.nm-dispatcher.service enabled
dbus-org.freedesktop.timesync1.service enabled
display-manager.service enabled
getty@.service enabled
lightdm.service enabled
ModemManager.service enabled
NetworkManager-dispatcher.service enabled
NetworkManager.service enabled
org.cups.cupsd.service enabled
systemd-fsck-root.service enabled-runtime
systemd-remount-fs.service enabled-runtime
systemd-timesyncd.service enabled
tlp-sleep.service enabled
tlp.service enabled
ufw.service enabled

相关服务对应的功能:

  • NetworkManager-wait-online.service:网络服务管理器,禁用后不影响正常的网络使用

  • autovt@.service:登陆相关 保留

  • avahi-daemon.service:让程序自动发现本地网络服务。除非你有兼容的设备或使用 zeroconf 协议的服务,否则应该关闭它。

  • service:蓝牙服务,如果使用也可以禁用

  • service:显卡驱动,保留

  • service:预定日程和时间触发事件的守护进程。保留

  • dbus-org.bluez.service:蓝牙守护进程,可禁止

  • dbus-org.freedesktop.Avahi.service:让程序自动发现本地网络服务。除非你有兼容的设备或使用 zeroconf 协议的服务,否则应该关闭它。

  • dbus-org.freedesktop.ModemManager1.service:用于提供移动宽频broadband(2G/3G/4G)接口。可禁用

  • dbus-org.freedesktop.NetworkManager.service:桌面网卡管理可禁用

  • dbus-org.freedesktop.nm-dispatcher.service:网卡守护进程,可禁用

  • dbus-org.freedesktop.timesync1.service:时间同步,可禁用

  • display-manager.service: 用来管理显示的生命周期,它决定如何根据当前连接的物理显示设备控制其逻辑显示,保留

  • getty@.service enabled:tty控制台相关,保留

  • service enabled:图形化界面显示,保留

  • service: 被 dbus 激活的守护进程,用于提供移动宽频broadband(2G/3G/4G)接口。可禁用

  • NetworkManager-dispatcher.service:网卡守护进程,可禁用

  • service:检测网络、自动连接网络的程序。建议保留

  • cups.cupsd.service:通用UNIX打印系统守护进程.,可禁用

  • systemd-fsck-root.service:负责对根文件系统进行检查,建议保留

  • systemd-remount-fs.service:在系统启动早期启动的服务,它会根据 fstab(5) 中设置的挂载选项,重新挂载根目录与 /usr 目录, 以及虚拟文件系统。这是一个必需的动作, 因为这些文件系统在能够读取 /etc/fstab 文件之前,就已经被预先挂载了, 例如在初始内存盘(initial RAM disk)中挂载、或在进入容器环境前挂载。保留

  • systemd-timesyncd.service:跨网络同步系统时钟的守护服务,可禁用

  • tlp-sleep.service:电池优化,电源管理,建议保留

  • service:电池优化,电源管理,建议保留

  • service: 防火墙服务,建议保留

本文转载自:「标点符」,原文:https://url.cn/5nL8bQZ,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com