Linux init系统:dinit, openrc, runit, s6的区别
Artix Linux 是基于 Arch Linux 但不使用 systemd 的发行版。它提供了几种不同的初始化系统(init systems)供用户选择。这四种系统的核心区别在于设计哲学、启动速度、配置难度以及对依赖项的处理。
以下是它们的详细对比:
1. Dinit
特点: 现代、快速、类 systemd 语法。
-
是什么: Dinit 是用 C++ 编写的现代初始化系统。它采用并行启动服务,支持服务间的依赖管理。
-
优势: 启动和关机速度极快;命令(
dinitctl)与systemctl比较接近,容易上手;原生支持用户服务。 -
缺点: 相对较新,社区积累的脚本和文档不如 OpenRC 丰富。
2. OpenRC
特点: 成熟、稳定、基于脚本。
-
是什么: 源自 Gentoo,是一个非常成熟的初始化系统。它基于 Shell 脚本工作,虽然也支持并行启动,但由于脚本解析的原因,速度通常略慢于 Dinit 或 Runit。
-
优势: 文档极其丰富(可以参考 Gentoo 和 Alpine 的资料);兼容性极佳;非常稳定。
-
缺点: 不具备原生的进程监控(Service Supervision,即程序崩溃后自动重启),需要额外配置。
3. Runit
特点: 极简、极致稳定、目录结构式。
-
是什么: runit 是由三阶段组成的极简 init,最早在 Void Linux 中出名。它通过文件系统的符号链接(link farm)来管理服务。
-
优势: 极致精简且非常稳定;进程监控非常强悍(秒级重启崩溃进程);结构透明。
-
缺点: 不支持自动依赖管理(你需要确保网络服务在依赖网络的服务之前启动);功能最少。
4. S6 (s6-rc)
特点: 模块化、极致灵活、面向高级用户。
-
是什么: 一个非常底层的、高度模块化的工具集。它将“启动、监控、依赖管理”拆分成不同的组件。
-
优势: 理论上最为完美和严谨的设计;对服务的控制粒度最细;性能极高。
-
缺点: 学习曲线最陡峭;修改服务配置后通常需要通过
s6-rc-compile编译数据库,对新手不友好。
哪个“最好用”?
“最好用”取决于你的需求和技术背景:
| 用户群体 | 推荐系统 | 理由 |
| 刚从 Systemd 转移过来 | Dinit | 语法熟悉,功能全面(带依赖管理),启动最快。 |
| 追求稳定与丰富文档 | OpenRC | 出错率低,遇到问题几乎都能在网上找到现成的脚本或教程。 |
| 追求极致简约/老手 | Runit | “它就是能动”,没有任何多余逻辑。 |
| 折腾控/追求极致控制 | S6 | 享受极致的模块化设计和进程管理艺术。 |
总结建议: 如果你是第一次尝试 Artix,建议选择 Dinit 或 OpenRC。Dinit 能给你带来类似 systemd 的现代化体验,而 OpenRC 则是最稳妥的选择。
初始化系统(Init System)是操作系统的基石。关于你提到的这几种系统,它们代表了两种截然不同的设计哲学:一种是**“全能集成式”(以 systemd 为代表),另一种是“极简模块化”**(Unix 哲学的践行者)。
一、 主流初始化系统优缺点对比
| 系统 | 核心定位 | 优点 | 缺点 |
| systemd | 现代 Linux 事实标准 | 强大的依赖管理、并行启动极快、统一管理日志/网络/硬件、生态极广。 | 极其臃肿(单体化)、二进制日志格式、违反 Unix 哲学、不可移植(仅限 Linux)。 |
| launchd | macOS 专用 | 统一管理所有后台任务、按需启动服务、设计超前。 | 仅限苹果生态、使用繁琐的 XML 配置、对自由软件社区不透明。 |
| OpenRC | 传统增强型 | 极其稳定、基于 Shell 脚本(易读)、兼容传统 SysVinit 脚本。 | 启动速度略慢(脚本解析)、原生进程监控能力弱、无内建并行机制。 |
| runit | 极致简约型 | 速度极快、代码量极小、进程监控非常强悍(崩溃自启)。 | 不支持复杂的自动依赖管理(需要手动控制启动顺序)。 |
| dinit | 现代简约型 | C++ 编写、支持服务依赖、并行启动、语法比 systemd 简洁。 | 社区规模较小,服务脚本积累不如 OpenRC 丰富。 |
| s6 | 技术派专家型 | 极致的模块化、设计极其严密且安全、支持复杂的进程树控制。 | 学习曲线最陡峭,配置极其繁琐(需要编译服务库)。 |
二、 为什么 Linux 社区中有人强烈排斥 systemd?
systemd 的争议不是性能问题,而是权力斗争和工程哲学的冲突。
1. 违反 Unix 哲学(Do one thing and do it well)
Unix 的核心原则是“只做一件事,并把它做好”。
-
systemd 的做法: 它不仅是 PID 1(初始化进程),它还接管了日志(journald)、网络(networkd)、登录管理(logind)、时间同步(timesyncd)、甚至挂载管理。
-
反对者的声音: 这让系统变得不可分割。如果你只想用 systemd 的服务管理,却不想用它的日志系统,你会发现它们深度耦合,极难拆分。
2. “臃肿”带来的安全隐患
-
攻击面增大: 作为 PID 1(系统权限最高的进程),systemd 包含了数百万行代码。在安全领域,代码越多,漏洞越多。一旦 systemd 崩溃,整个系统会立即陷入内核恐慌(Kernel Panic)。
-
复杂性灾难: 当系统出问题时,传统的 OpenRC 你可以通过阅读简单的 Shell 脚本定位故障;而 systemd 复杂的 C 源码和二进制组件让普通管理员难以进行底层排障。
3. 二进制日志(journald)
-
传统系统将日志存为纯文本,你可以用
grep、awk等任何工具处理,哪怕系统崩溃,挂载硬盘也能读日志。 -
systemd 使用二进制日志,必须使用专用工具
journalctl才能读取。如果日志文件损坏,可能整个日志库都无法打开。
4. 强行绑架开发者(Vendor Lock-in)
由于 systemd 提供了大量的底层 API(如 D-Bus 接口),很多桌面环境(如 GNOME)开始深度依赖 systemd。这意味着如果你想用 GNOME,你就被迫必须使用 systemd。这种“捆绑销售”引起了开发者对自由选择权的担忧。
三、 设计实现上的缺陷
-
非 POSIX 标准: systemd 大量使用了 Linux 内核特有的功能(如 cgroups, epoll),导致它完全无法移植到 BSD 或其他系统。这破坏了类 Unix 世界的跨平台共性。
-
大一统架构: 它试图在用户态构建一个类似于“宏内核”的结构,任何一个小模块的崩溃都可能波及 PID 1。
-
关机逻辑混乱: systemd 在处理某些僵死服务或挂载点时,经常会出现“等待 90 秒”无法关机的情况,且用户很难干预其超时逻辑。
总结建议
-
如果你是普通用户/开发者: systemd 是最好的选择,因为它省心,几乎所有软件都有现成的配置。
-
如果你是系统管理员/极致追求者:
-
追求稳定与传统选 OpenRC(Artix 或 Gentoo)。
-
追求启动速度与极简选 runit(Void Linux)。
-
想要平衡现代感与简洁选 dinit。
-
补充说明:
OpenRC
OpenRC 是一个基于依赖关系的初始化系统,最初与 sysvinit 保持兼容,但从 OpenRC 0.25 版本开始,它用自己的程序取代了 /sbin/init 由 Gentoo 开发人员编写,旨在供其他发行版和 BSD 系统使用。
Runit
runit 是一套工具,它提供了一个 init(PID 1)以及与 daemontools 兼容的进程监控框架,以及一些可以简化服务创建和维护的实用程序。
dinit
dinit 是一个具有依赖项支持的服务管理器,它也可以充当系统“init”程序。它的创建目的是提供一个可移植的、具有依赖项管理功能的 init 系统,其功能优于许多现有的 init 程序。
Dinit 可以并行启动多个服务,并进行依赖管理(例如,如果一个服务的运行依赖于另一个服务,则后者会先启动)。它可以监控服务对应的进程,并在进程崩溃时重新启动它,而且它能够以智能的方式执行此操作——首先“回滚”所有依赖服务,然后在依赖关系得到满足后重新启动它们。可以使用 dinitctl 工具来启动或停止服务并检查其状态。
Dinit 可以作为系统服务管理器运行(以 root 用户身份运行,使用系统路径进行配置),也可以作为用户进程运行(以用户身份运行,使用用户主目录中的路径进行配置)。
s6
s6 是一个进程监控套件,它还提供服务管理 ( s6-rc ) 和系统初始化/关闭 ( s6-linux-init ) 的工具。
s6 软件的设计理念是高度模块化,可以与其他组件灵活组合使用。同时,s6 软件之间也具备良好的协同工作能力。在 Artix,我们充分利用 s6 的各项功能,并使用所有可用工具为用户提供 /sbin/init、PID1、进程监控套件和服务管理器。
s6-linux-init 负责实际启动系统。它会将 tmpfs 挂载到 /run 目录,并将 /etc/s6/current/run-image 目录复制到 /run 。/sbin/init 随后会执行 s6-svscan 程序(由 s6 提供),该程序在机器的整个生命周期内 /sbin/init 作为 PID1 运行。完成此步骤后,初始化的第一阶段就完成了。除了作为 PID1 之外, s6-svscan 还是进程监控树的根进程。它会监控发现的每个服务,并为每个服务生成相应的 s6-supervise 进程。
此外,启动过程中会执行位于 /etc/ s6 /etc/s6/current/scripts 目录下的 rc.init 脚本。s6 本身并不进行服务管理,只负责进程监控。rc.init rc.init 会启动实际的服务管理器 s6-rc 。之后,我们会启动由 s6-rc 定义的默认运行级别,并启动所需的服务。
关闭时,s6-rc 中的所有服务都会停止运行,然后终止所有 s6-supervise 进程和其他进程,然后卸载所有内容,最后终止 s6-svscan 进程。
注意 :artix 上的 s6-linux-init 编译时启用了将消息打印到 /dev/console 指向 tty1。如果需要,您可以使用内核参数将 /dev/console 更改为其他位置(请参阅引导加载程序的配置)。
恢复 :s6-linux-init 始终在 tty12 上提供 getty 服务,可用于系统恢复(例如,在 s6-rc 崩溃的情况下)。只要系统能够正常启动,该服务就会一直存在。
systemd
https://wiki.artixlinux.org/Main/OpenRC
https://wiki.artixlinux.org/Main/Runit
https://wiki.artixlinux.org/Main/dinit
https://wiki.artixlinux.org/Main/S6

浙公网安备 33010602011771号