浅析 Linux 初始化 init 系统,第 3 部分: Systemd(2)

Systemd 的基本概念 单元的概念

系统初始化需要做的事情非常多。需要启动后台服务,比如启动 SSHD 服务;需要做配置工作,比如挂载文件系统。这个过程中的每一步都被 systemd 抽象为一个配置单元,即 unit。可以认为一个服务是一个配置单元;一个挂载点是一个配置单元;一个交换分区的配置是一个配置单元;等等。systemd 将配置单元归纳为以下一些不同的类型。然而,systemd 正在快速发展,新功能不断增加。所以配置单元类型可能在不久的将来继续增加。

每个配置单元都有一个对应的配置文件,系统管理员的任务就是编写和维护这些不同的配置文件,比如一个 MySQL 服务对应一个 mysql.service 文件。这种配置文件的语法非常简单,用户不需要再编写和维护复杂的系统 5 脚本了。

依赖关系

虽然 systemd 将大量的启动工作解除了依赖,使得它们可以并发启动。但还是存在有些任务,它们之间存在天生的依赖,不能用"套接字激活"(socket activation)、D-Bus activation 和 autofs 三大方法来解除依赖(三大方法详情见后续描述)。比如:挂载必须等待挂载点在文件系统中被创建;挂载也必须等待相应的物理设备就绪。为了解决这类依赖问题,systemd 的配置单元之间可以彼此定义依赖关系。

Systemd 用配置单元定义文件中的关键字来描述配置单元之间的依赖关系。比如:unit A 依赖 unit B,可以在 unit B 的定义中用"require A"来表示。这样 systemd 就会保证先启动 A 再启动 B。

Systemd 事务

Systemd 能保证事务完整性。Systemd 的事务概念和数据库中的有所不同,主要是为了保证多个依赖的配置单元之间没有环形引用。比如 unit A、B、C,假如它们的依赖关系为:

图 4, Unit 的循环依赖

图 4, Unit 的循环依赖

存在循环依赖,那么 systemd 将无法启动任意一个服务。此时 systemd 将会尝试解决这个问题,因为配置单元之间的依赖关系有两种:required 是强依赖;want 则是弱依赖,systemd 将去掉 wants 关键字指定的依赖看看是否能打破循环。如果无法修复,systemd 会报错。

Systemd 能够自动检测和修复这类配置错误,极大地减轻了管理员的排错负担。

Target 和运行级别

systemd 用目标(target)替代了运行级别的概念,提供了更大的灵活性,如您可以继承一个已有的目标,并添加其它服务,来创建自己的目标。下表列举了 systemd 下的目标和常见 runlevel 的对应关系:

表 1. Sysvinit 运行级别和 systemd 目标的对应表 Sysvinit 运行级别Systemd 目标备注
0   runlevel0.target, poweroff.target   关闭系统。  
1, s, single   runlevel1.target, rescue.target   单用户模式。  
2, 4   runlevel2.target, runlevel4.target, multi-user.target   用户定义/域特定运行级别。默认等同于 3。  
3   runlevel3.target, multi-user.target   多用户,非图形化。用户可以通过多个控制台或网络登录。  
5   runlevel5.target, graphical.target   多用户,图形化。通常为所有运行级别 3 的服务外加图形化登录。  
6   runlevel6.target, reboot.target   重启  
emergency   emergency.target   紧急 Shell  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/17126.html