Linux init 与 systemd 启动区别解析

12次阅读

init 串行启动依赖脚本顺序,systemd 并行启动通过显式依赖自动拓扑排序;前者耗时长、易出错,后者启动快、依赖明确但需正确配置 wants/after 等字段。

Linux init 与 systemd 启动区别解析

init 是串行启动,systemd 是并行启动

根本区别就在这儿:init 启动服务像排队打饭,一个接一个;systemd 则像食堂开多个窗口,能同时处理几十个请求。这直接决定了系统从加电到登录的耗时——老式 CentOS 6 在 100+ 服务下常需 90 秒以上,而 systemd 的 CentOS 7/8 通常 20–40 秒内完成。

  • init 依赖 /etc/inittab/etc/rc.d/rcX.d/ 下的符号链接顺序,脚本里没写好依赖(比如数据库没启完就跑应用),就会报错或卡住
  • systemdWants=After=Requires= 显式声明依赖,它会自动拓扑排序,但写错关系(比如把 After=network.target 写成 After=network.service)会导致服务迟迟不启动
  • 注意:systemd 的并行不是“无脑并发”,它仍受 cgroup 资源限制和 socket 激活机制约束;某些服务(如 udevsystemd-journald)必须优先就绪,否则整个链路阻塞

运行级别(runlevel)vs 目标(target)

你敲 runlevel 看到的数字(比如 35),在 init 里是硬编码状态;在 systemd 里只是 multi-user.targetgraphical.target 的别名——本质是软链接,可自由重定向。

  • 查当前目标:systemctl get-default;改默认目标:systemctl set-default multi-user.target(别再用 init 3,那只是兼容层,实际走的是 systemd 的 target 切换)
  • runlevel 命令输出的“N 3”中 N 表示上次运行级别未变,3 是当前,但它已不参与真实控制——真正起作用的是 systemctl list-units --type=target --state=active
  • 常见陷阱:有人把自定义 service 加入 rc.local,却忘了 /etc/rc.d/rc.local 在 systemd 下默认不执行,必须先 chmod +x /etc/rc.d/rc.localsystemctl enable rc-local

服务管理命令完全不兼容

别指望 service httpd startsystemctl start httpd 只是换了个命令名——背后加载的配置路径、环境变量、日志归属、甚至进程树结构都不同。

  • service 调用的是 /etc/init.d/httpd 脚本,它自己解析 start 参数、手动 fork、自己管 pidfile;systemctl 直接读 /usr/lib/systemd/system/httpd.service,由 systemd 统一 fork+ 监控 +cgroup 隔离
  • 旧脚本里写的 daemonpidfilestatus 函数,在 systemd 下全被忽略;若服务没提供 .service 文件,systemctl 会 fallback 到 service 兼容模式,但无法做依赖管理、重启策略、资源限制
  • 查日志别用 tail -f /var/log/messages,要用 journalctl -u httpd -f;否则你看不到 systemd 封装后的启动上下文(比如为什么 failed、cgroup 内存超限、seccomp 拒绝了某个 syscall)

开机自启的本质是软链接,不是改配置文件

很多人以为 systemctl enable httpd 是往某个配置里写了一行,其实它只干一件事:在 /etc/systemd/system/multi-user.target.wants/ 下建个指向 /usr/lib/systemd/system/httpd.service 的软链接。

  • 这个软链接才是 systemd 开机时真正扫描并加载的依据;删掉它,systemctl is-enabled httpd 就返回 disabled,哪怕 .service 文件里写了 WantedBy=multi-user.target
  • 如果你手动改了 /usr/lib/systemd/system/httpd.service,必须执行 systemctl daemon-reload 才能让改动生效;否则 systemctl status 显示的仍是旧缓存
  • 切记:不要在 /etc/systemd/system/ 下直接放新 service 文件后就 enable,得先 systemctl daemon-reload,否则 enable 会失败并报“No such file or directory”—— 因为 systemd 还没扫描到它

最易被忽略的一点:systemd 的 default.target 不等于“图形界面开关”。即使你设了 graphical.target,只要显卡驱动没加载、Display Manager(如 gdm)没注册为 Wants=,它照样进不了桌面。init 时代靠 runlevel 数字“猜状态”,systemd 要求你真正理清每个单元的激活路径。

text=ZqhQzanResources