systemd 能延迟 一个单元的启动 直到它被需要。 这个操作 是这样的:
1.你创建了一个 systemd 单元A,一个系统服务;
2.你指定了一个系统资源,像是:网络端口/socket,文件 或者 设备,单元A 用这个来提供 服务;
3.你创建了另一个 systemd 单元,单元R,来表示那个 资源。这些 资源单元 被分类成 各种类型:socket 单元,路径单元 和 设备单元。
4.你定义了 单元A 和 单元R 的关系。一般来说,这个关系是 隐含的 基于单元的名字,但也可以是 直白的。
建好了单元,操作继续:
1.从单元R 启动起,systemd 监控了 这个资源;
2.systemd 阻塞了这个资源,缓存了对这个 资源 的输入。
3. systemd 启动了 单元A
4. 然后,单元A 控制了 这个资源,读取了缓存中数据。
这有些重点:
1.你得确定 你的资源单元 包含了需要的每一个 资源。这好办,大多数服务只需要一个资源;
2.你得确认 你的资源单元 有绑定到 你的服务单元。
3.不是所有的服务器 都知道 如何与 资源单元 交互。
systemd 和以前的 组件 有很多相似的地方。
一个 socket Unit 和 一个 服务unit
一个简单的 网络 回声服务。
回声服务是 回复 接收到的任何信息;程序监听 tcp 端口 22222.例子,echo.socket:
上面那个配置文件,没有提到 它对应的 服务单元。
服务单元 和 资源单元的关联 是通过命名规范。比如:echo.socket 和 echo@.service。echo@.service:
也可以通过 socket=XXX.socket 来创建关联。
启动 资源 单元:
# systemctl start echo.socket
用telnet 来测试:
关掉服务:
# systemctl stop echo.socket
多个实例 和 交付
因为 echo@.service 名字里有个 @,它支持多个实例(@表示 参数化)。Accept=true 表示systemd 同时接收多个链接,并为每个链接 创建 服务实例。每个实例 从连接里读出数据 作为 标准输出。
service unit 只能构建 这个难度的 网络服务。
如果 服务单元 能接收连接,不要把 @放在它的名字里,也不要在 socket 单元里写 acceppt=True。
有很多不同的资源 可以传递给 服务单元,这使得分类归纳 很困难。资源相关 的单元,看systemd.socket(5) systemd.path(5) 和 systemd.device(5)。服务 单元 看 systemd.exec(5)
用协助单元 来启动优化
systemd 要简化 依赖的顺序 和 加快启动时间。资源单元 是按需启动。一个服务单元,一个协助单元:协助单元 代表 服务单元 需要的资源。systemd 会在 启动 协助单元的时候,启动 服务单元。
有些 开机启动的 服务单元 需要些时间,其有其他单元 还依赖他们。systemd 的 单元关键资源 能让他们同时启动。
传统的顺序启动系统:
服务E 启动后 带来了 关键资源R。服务A B C 都依赖这个关键资源,而且他们只能挨个 启动。
单元R 代表了 单元E 提供的资源。当 systemd 启动 单元E 的时候,systemd 也提供了 访问 单元R 的接口。这个时候,单元 A B C 可以同时启动。单元E 启动后 便接管 单元R。
journald 和 dbus 单元 就是这样并行 启动的。