CentOS 7 之systemd管理(2)

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

Systemd事务:

Systemd 能保证事务完整性。Systemd 的事务概念和数据库中的有所不同,主要是为了保证多个依赖的配置单元之间没有环形引用。 存在循环依赖,那么 systemd 将无法启动任意一个服务。此时systemd 将会尝试解决这个问题,因为配置单元之间的依赖关系有两种:required是强依赖;want 则是弱依赖,systemd 将去掉 wants 关键字指定的依赖看看是否能打破循环。如果无法修复,systemd会报错。

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

Target和运行级别:

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

CentOS 7 之systemd管理

CentOS7/RHEL7 systemd详解   

为什么systemd会被如此迅速的采用?

systemd 与 sysVinit 彩版对照表

太有用了!用systemd命令来管理Linux系统! 

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

Systemd 的并发启动原理

如前所述,在 Systemd 中,所有的服务都并发启动,比如Avahi、D-Bus、livirtd、X11、HAL 可以同时启动。乍一看,这似乎有点儿问题,比如 Avahi 需要syslog 的服务,Avahi 和syslog 同时启动,假设 Avahi 的启动比较快,所以syslog 还没有准备好,可是 Avahi 又需要记录日志,这岂不是会出现问题?

Systemd 的开发人员仔细研究了服务之间相互依赖的本质问题,发现所谓依赖可以分为三个具体的类型,而每一个类型实际上都可以通过相应的技术解除依赖关系。

•并发启动原理之一:解决 socket 依赖

绝大多数的服务依赖是套接字依赖。比如服务A 通过一个套接字端口S1 提供自己的服务,其他的服务如果需要服务A,则需要连接S1。因此如果服务A 尚未启动,S1就不存在,其他的服务就会得到启动错误。所以传统地,人们需要先启动服务A,等待它进入就绪状态,再启动其他需要它的服务。Systemd认为,只要我们预先把S1 建立好,那么其他所有的服务就可以同时启动而无需等待服务A 来创建S1 了。如果服务A 尚未启动,那么其他进程向S1 发送的服务请求实际上会被Linux 操作系统缓存,其他进程会在这个请求的地方等待。一旦服务A 启动就绪,就可以立即处理缓存的请求,一切都开始正常运行。

那么服务如何使用由 init 进程创建的套接字呢?

Linux 操作系统有一个特性,当进程调用fork 或者exec 创建子进程之后,所有在父进程中被打开的文件句柄(file descriptor) 都被子进程所继承。套接字也是一种文件句柄,进程A 可以创建一个套接字,此后当进程A 调用 exec 启动一个新的子进程时,只要确保该套接字的close_on_exec 标志位被清空,那么新的子进程就可以继承这个套接字。子进程看到的套接字和父进程创建的套接字是同一个系统套接字,就仿佛这个套接字是子进程自己创建的一样,没有任何区别。

这个特性以前被一个叫做 inetd 的系统服务所利用。Inetd 进程会负责监控一些常用套接字端口,比如Telnet,当该端口有连接请求时,inetd才启动 telnetd 进程,并把有连接的套接字传递给新的telnetd 进程进行处理。这样,当系统没有telnet 客户端连接时,就不需要启动telnetd 进程。Inetd可以代理很多的网络服务,这样就可以节约很多的系统负载和内存资源,只有当有真正的连接请求时才启动相应服务,并把套接字传递给相应的服务进程。

和 inetd 类似,systemd 是所有其他进程的父进程,它可以先建立所有需要的套接字,然后在调用exec 的时候将该套接字传递给新的服务进程,而新进程直接使用该套接字进行服务即可。

•并发启动原理之二:解决 D-Bus 依赖

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

转载注明出处:https://www.heiqu.com/15899.html