Linux系統啟動速度最佳化工具systemd-analyze

yooooooo發表於2024-09-10

systemd-analyze簡介

systemd-analyze是Linux自帶的分析系統啟動效能的工具。

systemd-analyze可使用的命令:

  • 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實戰

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

可以看到開機用了23秒以上。接下來查詢下這鍋應該誰背:

➜~ 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秒。這裡的記時有可能是等待其他伺服器啟動的,再來看看其關聯服務的啟動時間:

➜ ~ 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秒怎麼多。

發現了影響啟動的服務,最簡單的方式是禁用此服務:

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

方案二:編輯/lib/systemd/system/NetworkManager-wait-online.service檔案,將檔案中的

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

超時時間由30改為10

另外,我們來看下還有哪些開機啟動的服務可被最佳化:

➜ ~ 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: 防火牆服務,建議保留

相關文章