上篇文章讲了systemd 的service和target的使用配置方法,本文主要介绍systemd下的systemd-analyze工具,用于分析Linux启动性能。
通过 systemd-analyze 不同命令,可以了解系统启动的总体时间、各个系统服务/Unit启动时间以及关键耗时路径,帮助我们分析和优化系统的启动性能。
系统启动时间统计
systemd-analyze
$ systemd-analyze
Startup finished in 12.055s (firmware) + 4.938s (loader) + 2.018s (kernel) + 8.514s (userspace) = 27.526s
graphical.target reached after 8.463s in userspace
这里显示了firmware+loader+kernel+userspace 四部分时间,有的人只显示了kernel+userspace两部分时间,可能因为我是ubuntu笔记本缘故,BIOS的启动时间也计算进来了。
系统服务/unit 启动时间排序
如果要查看每个unit/service的启动时间,使用systemd-analyze blame
,会从大到小进行排序。
$ systemd-analyze blame
5d 3h 7min 29.775s dev-loop18.device
1min 47.741s apt-daily-upgrade.service
1min 17.020s fstrim.service
6.582s NetworkManager-wait-online.service
1.036s gpu-manager.service
843ms snapd.service
615ms systemd-oomd.service
592ms systemd-binfmt.service
584ms proc-sys-fs-binfmt_misc.mount
575ms apparmor.service
491ms apt-daily.service
354ms snapd.seeded.service
352ms systemd-resolved.service
325ms docker.service
220ms dev-loop7.device
220ms dev-loop4.device
220ms dev-loop6.device
219ms dev-loop0.device
219ms dev-loop1.device
219ms dev-loop2.device
219ms dev-loop3.device
217ms man-db.service
203ms dev-nvme0n1p5.device
194ms ua-timer.service
180ms networkd-dispatcher.service
178ms snapd.apparmor.service
....
....
关键耗时路径
systemd-analyze critical-chain
打印严重消耗时间的启动服务树状图,直观看出各unit依赖关系。
如果要查看指定service的启动耗时树状图,可执行:systemd-analyze critical-chain [UNIT]
“@”后面的时刻表示该单元的启动时刻;“+”后面的时长表示该单元总计花了多长时间才完成启动。不过需要注意的是, 这些信息也可能具有误导性, 因为花费较长时间启动的单元, 有可能只是在等待另一个依赖单元完成启动。最好再查看下上下依赖单元启动情况。
如下:NetworkManager-wait-online.service是耗时的关键服务。从上到下为启动的顺序的依赖关系。
$ systemd-analyze critical-chain
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.
graphical.target @8.463s
└─multi-user.target @8.463s
└─docker.service @8.138s +325ms
└─network-online.target @8.094s
└─NetworkManager-wait-online.service @1.511s +6.582s
└─NetworkManager.service @1.453s +51ms
└─dbus.service @1.450s
└─basic.target @1.439s
└─sockets.target @1.439s
└─snapd.socket @1.437s +589us
└─sysinit.target @1.400s
└─systemd-backlight@backlight:intel_backlight.service @3.705s +4ms
└─system-systemd\x2dbacklight.slice @3.656s
└─system.slice @192ms
└─-.slice @192ms
可视化显示
systemd-analyze plot > systemd.svg
用于将服务的启动顺序与时间通过图形化展示,浏览器打开svg文件可以直观看出来。
优化思路
主要通过上述的systemd-analyze找出各个服务的启动时间,可能还会结合systemctl list-unit-files --type=service | grep enabled
查看哪些服务被enable。然后根据实际使用场景,可以优化点有:
- disable 掉一些不必要的服务。
- 调整启动顺序,减少服务之间不必要的依赖等待。
- 并行启动相关服务。
- 优化具体耗时服务的启动程序代码。