Сокращение времени загрузки системы — не просто академическое упражнение. Для разработчиков, работающих с физическими серверами, встраиваемыми системами или просто ценящих скорость отклика, каждые 500 мс имеют значение. В Arch Linux, где контроль над системой практически неограничен, инструменты systemd предоставляют детализированный аппарат для оптимизации. Рассмотрим не только рутинное использование systemd-analyze
, но и методы тонкой настройки зависимостей, анализа критических цепочек и работы с параметрами ядра.
Анализируем исходное состояние
Начнем с базовой диагностики. Команда systemd-analyze time
покажет общее время загрузки ядра (kernel
) и пользовательского пространства (userspace
). Но настоящая информация скрывается в деталях:
$ systemd-analyze blame --no-pager | head -n 5
5.212s NetworkManager-wait-online.service
3.874s dev-sda3.device
2.945s systemd-cryptsetup@nvme0n1p2.service
1.879s systemd-udev-settle.service
874ms docker.service
Эти данные часто вводят в заблуждение. Например, dev-sda3.device
выглядит как самодостаточная единица замедления, но на практике это маркер ожидания блочного устройства, которое, в свою очередь, может блокировать другие сервисы. Для выявления фактических зависимостей используем:
$ systemd-analyze critical-chain docker.service
The time after the unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.
docker.service @1.879s +874ms
└─network-online.target @1.878s
└─NetworkManager-wait-online.service @3.090s +5.212s
└─NetworkManager.service @875ms +1.682s
Здесь очевидно: docker.service
ждет network-online.target
, который зависит от медленного NetworkManager-wait-online.service
. Это классический случай чрезмерно строгих зависимостей в systemd-юнитах.
Стратегии оптимизации сервисов
Переопределение конфигурации systemd
Маскировка ненужных сервисов (например, ModemManager
для серверных установок) — очевидный шаг:
sudo systemctl mask ModemManager.service
Более интересен пример с NetworkManager-wait-online.service
. Вместо полного отключения (что нарушит службы, требующие готовой сети), изменим его поведение:
sudo systemctl edit NetworkManager-wait-online.service
Добавляем секцию для ограничения времени ожидания:
[Service]
TimeoutStartSec=10s
ExecStart=
ExecStart=/usr/bin/nm-online -s -q --timeout=10
Модификация ExecStart
с предварительной очисткой предыдущего значения (отсюда пустая строка) и установка таймаута уменьшит потенциальный простой.
Параллелизация инициализации
Systemd по умолчанию загружает сервисы с явными зависимостями последовательно. Переход к параллельной загрузке требует декомпозиции зависимостей. Например, для службы docker.service
можно устранить зависимость от network-online.target
, если приложение допускает временную недоступность сети:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf
[Unit]
After=network.target
Wants=network.target
Это заменяет более строгое After=network-online.target
, потенциально выводя запуск docker из критической цепочки сетевой инициализации.
Тонкая настройка ядра и initramfs
Время инициализации ядра (kernel
) недооценивают. Анализ через dmesg
с timestamp:
$ dmesg -T | grep -E '\[.*\]' | tail -n 5
Вывод покажет узкие места при загрузке устройств. Для SSD и NVMe дисков часто помогает отключение лишних модулей ядра. В файле /etc/mkinitcpio.conf
удалите ненужные хуки (например, usbinput
для серверов):
-HOOKS=(base systemd autodetect keyboard modconf block sd-encrypt filesystems fsck)
+HOOKS=(base systemd autodetect modconf block sd-encrypt filesystems fsck)
После обновления конфигурации пересобираем образ:
sudo mkinitcpio -P
Для систем с UEFI дополнительный выигрыш дает сокращение времени ожидания загрузчика. В /boot/loader/loader.conf
:
timeout 3
console-mode 2
Автоматизация анализа
Статическая оптимизация — только начало. Реализуем динамический мониторинг с помощью systemd-аналитики:
#!/bin/bash
journalctl --boot=0 -o short-monotonic
| awk '/Starting User Manager/ {start=1}
start && /Starting (.+)\.service/ {svc=$0; sub(/.*Starting /,"",svc); print svc}'
| sort | uniq -c | sort -n
Этот скрипт выявляет наиболее часто перезапускаемые сервисы во время загрузки — кандидаты на консолидацию или отложенную инициализацию.
Вывод: баланс скорости и функциональности
Оптимизация времени загрузки в Arch Linux — не гонка за абстрактными миллисекундами. Речь о согласовании системных требований с реальными рабочими сценариями. Осмысленное управление зависимостями systemd, точечная настройка параметров ядра и регулярный анализ через инструменты вроде systemd-analyze plot > boot.svg
создают систему, где скорость не противоречит стабильности. Критически важные сервисы сохраняют приоритет, а второстепенные компоненты переходят в фоновый режим — современный подход к управлению временем инициализации.