systemd.service 服务单元配置

本文档详细介绍了systemd.service服务单元配置,包括服务模板、自动依赖、启动类型、命令行选项等内容。服务单元配置涉及到如启动完成的判断、进程通信、依赖关系管理以及服务生命周期管理等多个方面,是理解systemd服务管理的关键。
摘要由CSDN通过智能技术生成

 

systemd.service — 服务单元配置

大纲

service.service

描述

以 ".service" 为后缀的单元文件, 封装了一个被 systemd 监视与控制的进程。

本手册列出了所有专用于此类单元的 配置选项(亦称"配置指令"或"单元属性")。 systemd.unit(5) 中描述了通用于所有单元类型的配置选项, 它们位于 "[Unit]" 与 "[Install]" 小节。 此类单元专用的配置选项 位于 "[Service]" 小节。

其他可用的选项参见 systemd.exec(5) 手册(定义了命令的执行环境), 以及 systemd.kill(5) 手册(定义了如何结束进程), 以及 systemd.resource-control(5) 手册(定义了进程的 资源控制)。

如果要求启动或停止的某个单元文件 不存在, systemd 将会寻找同名的SysV初始化脚本(去掉 .service 后缀), 并根据那个同名脚本, 动态的创建一个 service 单元。 这主要用于与传统的SysV兼容(不能保证100%兼容)。 更多与SysV的兼容性可参见 Incompatibilities with SysV 文档。

服务模板

systemd 服务可以通过 "service@argument.service" 语法接受一个单独的参数。这样的服务被称为"实例化"服务,而不带 argument 参数的服务单元定义被称为"模板"。例如dhcpcd@.service 服务模板接受一个网络接口参数之后, 就生成了一个实例化服务。在服务单元模板文件内部, 可以通过 %-specifiers 引用参数(也称为"实例名")。详见systemd.unit(5) 手册。

自动依赖

隐含依赖

下列依赖关系是自动隐含的:

  • 设置了 Type=dbus 的服务会自动添加 Requires=dbus.socket 与 After=dbus.socket 依赖。

  • 基于套接字启动的服务会自动添加对关联的 .socket 单元的 After= 依赖。 服务单元还会为所有在 Sockets= 中列出的 .socket 单元自动添加 Wants= 与 After= 依赖。

还有一些 其他依赖关系是由 systemd.exec(5) 与 systemd.resource-control(5) 中的某些资源限制选项自动隐含添加的。

默认依赖

除非明确设置了 DefaultDependencies=no ,否则 service 单元将会自动添加下列依赖关系:

  • Requires=sysinit.targetAfter=sysinit.targetAfter=basic.targetConflicts=shutdown.targetBefore=shutdown.target 。 这样可以确保普通的服务单元: (1)在基础系统启动完毕之后才开始启动,(2)在关闭系统之前先被干净的停止。 只有那些需要在系统启动的早期就必须启动的服务, 以及那些必须在关机动作的结尾才能停止的服务才需要设置 DefaultDependencies=no 。

  • 从同一个模版实例化出来的所有服务单元(单元名称中带有 "@" 字符), 默认全部属于与模版同名的同一个 slice 单元(参见 systemd.slice(5))。 该同名 slice 一般在系统关机时,与所有模版实例一起停止。 如果你不希望像上面这样,那么可以在模版单元中明确设置 DefaultDependencies=no , 并且:要么在该模版文件中明确定义特定的 slice 单元(同样也要明确设置 DefaultDependencies=no)、 要么在该模版文件中明确设置 Slice=system.slice (或其他合适的 slice)。 参见 systemd.resource-control(5) 手册。

选项

每个服务单元文件都必须包含一个 [Service] 小节。 由于此小节中的许多选项也 同时适用于其他类型的单元, 所以本手册仅记录了专用于服务单元的选项。 其他共享的选项参见systemd.exec(5)systemd.kill(5)systemd.resource-control(5) 手册。 这里只列出仅能用于 [Service] 小节的 选项(亦称"指令"或"属性"):

Type=

设置进程的启动类型。必须设为 simpleexecforkingoneshotdbusnotifyidle 之一:

  • 如果设为 simple (当设置了 ExecStart= 、 但是没有设置 Type= 与 BusName= 时,这是默认值), 那么 ExecStart= 进程就是该服务的主进程, 并且 systemd 会认为在创建了该服务的主服务进程之后,该服务就已经启动完成。 如果此进程需要为系统中的其他进程提供服务, 那么必须在该服务启动之前先建立好通信渠道(例如套接字), 这样,在创建主服务进程之后、执行主服务进程之前,即可启动后继单元, 从而加快了后继单元的启动速度。 这就意味着对于 simple 类型的服务来说, 即使不能成功调用主服务进程(例如 User= 不存在、或者二进制可执行文件不存在), systemctl start 也仍然会执行成功。

  • exec 与 simple 类似,不同之处在于, 只有在该服务的主服务进程执行完成之后,systemd 才会认为该服务启动完成。 其他后继单元必须一直阻塞到这个时间点之后才能继续启动。换句话说, simple 表示当 fork() 函数返回时,即算是启动完成,而 exec 则表示仅在 fork() 与 execve() 函数都执行成功时,才算是启动完成。 这就意味着对于 exec 类型的服务来说, 如果不能成功调用主服务进程(例如 User= 不存在、或者二进制可执行文件不存在), 那么 systemctl start 将会执行失败。

  • 如果设为 forking ,那么表示 ExecStart= 进程将会在启动过程中使用 fork() 系统调用。 也就是当所有通信渠道都已建好、启动亦已成功之后,父进程将会退出,而子进程将作为主服务进程继续运行。 这是传统UNIX守护进程的经典做法。 在这种情况下,systemd 会认为在父进程退出之后,该服务就已经启动完成。 如果使用了此种类型,那么建议同时设置 PIDFile= 选项,以帮助 systemd 准确可靠的定位该服务的主进程。 systemd 将会在父进程退出之后 立即开始启动后继单元。

  • oneshot 与 simple 类似,不同之处在于, 只有在该服务的主服务进程退出之后,systemd 才会认为该服务启动完成,才会开始启动后继单元。 此种类型的服务通常需要设置 RemainAfterExit= 选项。 当 Type= 与 ExecStart= 都没有设置时, Type=oneshot 就是默认值。

  • dbus 与 simple 类似,不同之处在于, 该服务只有获得了 BusName= 指定的 D-Bus 名称之后,systemd 才会认为该服务启动完成,才会开始启动后继单元。 设为此类型相当于隐含的依赖于 dbus.socket 单元。 当设置了 BusName= 时, 此类型就是默认值。

  • notify 与 exec 类似,不同之处在于, 该服务将会在启动完成之后通过 sd_notify(3) 之类的接口发送一个通知消息。systemd 将会在启动后继单元之前, 首先确保该进程已经成功的发送了这个消息。如果设为此类型,那么下文的 NotifyAccess= 将只能设为非 none 值。如果未设置 NotifyAccess= 选项、或者已经被明确设为 none ,那么将会被自动强制修改为 main 。注意,目前 Type=notify 尚不能与 PrivateNetwork=yes 一起使用。

  • idle 与 simple 类似,不同之处在于, 服务进程将会被延迟到所有活动任务都完成之后再执行。 这样可以避免控制台上的状态信息与shell脚本的输出混杂在一起。 注意:(1)仅可用于改善控制台输出,切勿将其用于不同单元之间的排序工具; (2)延迟最多不超过5秒, 超时后将无条件的启动服务进程。

建议对长时间持续运行的服务尽可能使用 Type=simple (这是最简单和速度最快的选择)。 注意,因为 simple 类型的服务 无法报告启动失败、也无法在服务完成初始化后对其他单元进行排序, 所以,当客户端需要通过仅由该服务本身创建的IPC通道(而非由 systemd 创建的套接字或 D-bus 之类)连接到该服务的时候, simple 类型并不是最佳选择。在这种情况下, notify 或 dbus(该服务必须提供 D-Bus 接口) 才是最佳选择, 因为这两种类型都允许服务进程精确的安排 何时算是服务启动成功、何时可以继续启动后继单元。 notify 类型需要服务进程明确使用 sd_notify() 函数或类似的API, 否则,可以使用 forking 作为替代(它支持传统的UNIX服务启动协议)。 最后,如果能够确保服务进程调用成功、服务进程自身不做或只做很少的初始化工作(且不大可能初始化失败), 那么 exec 将是最佳选择。 注意,因为使用任何 simple 之外的类型都需要等待服务完成初始化,所以可能会减慢系统启动速度。 因此,应该尽可能避免使用 simple 之外的类型(除非必须)。另外,也不建议对长时间持续运行的服务使用 idle 或 oneshot 类型。

RemainAfterExit=

当该服务的所有进程全部退出之后, 是否依然将此服务视为活动(active)状态。 默认值为 no

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值