我想将 gammu-smsd 服务迁移到 mariadb,所以我编辑了服务- 我在 After 行中systemctl edit --full gammu-smsd.service
添加了。mariadb.service
[Unit]
Description=SMS daemon for Gammu
Documentation=man:gammu-smsd(1)
After=mariadb.service postgresql.service network-online.target
检查 mariadb 是否存在systemctl list-units --type=service
::
mariadb.service loaded active running MariaDB 10.3.15 database server
但我没有在任何地方看到新的依赖关系:
systemctl list-dependencies gammu-smsd.service
gammu-smsd.service
● ├─system.slice
● └─sysinit.target
● ├─dev-hugepages.mount
● ├─dev-mqueue.mount
● ├─fake-hwclock.service
● ├─keyboard-setup.service
● ├─kmod-static-nodes.service
● ├─proc-sys-fs-binfmt_misc.automount
● ├─resolvconf.service
● ├─sys-fs-fuse-connections.mount
● ├─sys-kernel-config.mount
● ├─sys-kernel-debug.mount
● ├─systemd-ask-password-console.path
● ├─systemd-binfmt.service
● ├─systemd-hwdb-update.service
● ├─systemd-journal-flush.service
● ├─systemd-journald.service
● ├─systemd-machine-id-commit.service
● ├─systemd-modules-load.service
● ├─systemd-random-seed.service
● ├─systemd-sysctl.service
● ├─systemd-sysusers.service
● ├─systemd-tmpfiles-setup-dev.service
● ├─systemd-tmpfiles-setup.service
● ├─systemd-udev-trigger.service
● ├─systemd-udevd.service
● ├─systemd-update-utmp.service
● ├─cryptsetup.target
● ├─local-fs.target
● │ ├─-.mount
● │ ├─boot.mount
● │ ├─DietPi.mount
● │ ├─systemd-fsck-root.service
● │ ├─systemd-remount-fs.service
● │ ├─tmp.mount
● │ └─var-log.mount
● └─swap.target
● └─var-swap.swap
此外,gammu-smsd 在 maria DB 准备就绪之前启动。有人能指出我做错了什么吗?谢谢!
答案1
After=
仅确保该服务在其他服务之后启动,如果两项服务均已激活。
如果你想要真正依赖 mariadb,你必须使用Requires=
或Wants=
。这定义了以下行为:
- 如果你激活gammu-smsd,玛丽亚数据库也将被激活
- 如果gammu-smsd正在开始玛丽亚数据库未运行,将为您启动
- 如果玛丽亚数据库被阻止了,gammu-smsd正在运行,它将为您停止
通常你还是会想使用After=
,因为Require=
和Wants=
不能保证顺序。如果你只使用Requires=
或Wants=
gammu-smsd可以同时或之前开始玛丽亚数据库。
如果你使用Require=
和After=
gammu-smsd如果玛丽亚数据库无法启动。哪里Wants=
仍会得到gammu-smsd开始,如果玛丽亚数据库无法启动。gammu-smsd RPM 的作者可能将 mariadb 和 postgresql 的 After 放在那里,这样你就可以通过激活相应的服务来选择其中一个、两个或都不激活。
实际上,你不一定需要Requires=
在Wants=
gammu-smsd配置。只需确保玛丽亚数据库已激活。
您的问题可能是,mariadb 已成功进入运行状态,但仍未准备好接受连接。至少在 RHEL 上,mariadb 的配置是这样的,Type=simple
这意味着一旦 mariadb 进程启动,它就会立即进入运行状态,即使它尚未接受连接。
一个简单而又不成熟的处理方式就是在gammu-smsd和:
ExecStartPre=/bin/sleep 30
更高级的方法是使用如下方法:https://github.com/vishnubob/wait-for-it。
欲了解更多信息,请阅读systemd.unit和systemd.service。
类型=
配置此服务单元的进程启动类型。simple、exec、forking、oneshot、dbus、notify 或 idle 之一:
如果设置为简单(如果指定了 ExecStart= 但未指定 Type= 和 BusName=,则为默认值),服务管理器将在主服务进程分叉后立即启动该单元。预计使用 ExecStart= 配置的进程是服务的主进程。在这种模式下,如果进程为系统上的其他进程提供功能,则应在启动服务之前安装其通信通道(例如,由 systemd 通过套接字激活设置的套接字),因为服务管理器将在创建主服务进程之后、执行服务的二进制文件之前立即启动后续单元。请注意,这意味着即使无法成功调用服务的二进制文件(例如,因为选定的 User= 不存在或服务二进制文件丢失),简单服务的 systemctl start 命令行也会报告成功。
要求=
配置对其他单元的依赖关系。如果此单元被激活,则此处列出的单元也将被激活。如果其他单元之一无法激活,并且设置了对失败单元的 After= 排序依赖,则不会启动此单元。此外,无论是否指定 After=,如果明确停止其他单元之一,则将停止此单元。可以多次指定此选项,也可以在一个选项中指定多个以空格分隔的单元,在这种情况下将创建所有列出名称的依赖关系。请注意,依赖关系不会影响服务启动或停止的顺序。这必须使用 After= 或 Before= 选项单独配置。如果单元 foo.service 需要单元 bar.service(使用 Requires= 配置),并且未使用 After= 或 Before= 配置排序,则如果 foo.service 被激活,则两个单元将同时启动,并且它们之间没有任何延迟。通常,为了实现在处理失败服务时更强大的系统,使用 Wants= 而不是 Requires= 是更好的选择。
请注意,此依赖类型并不意味着当此单元运行时,其他单元必须始终处于活动状态。具体来说:条件检查失败(例如 ConditionPathExists=、ConditionPathIsSymbolicLink=、… — 见下文)不会导致具有 Requires= 依赖关系的单元的启动作业失败。此外,某些单元类型可能会自行停用(例如,服务进程可能决定干净退出,或者设备可能被用户拔出),这不会传播到具有 Requires= 依赖关系的单元。将 BindsTo= 依赖类型与 After= 一起使用可确保单元永远不会处于活动状态,除非有其他特定单元也处于活动状态(见下文)。
请注意,也可以通过向单元文件附带的 .requires/ 目录添加符号链接,在单元配置文件之外配置此类型的依赖项。有关详细信息,请参阅上文。
想要=
Requires= 的弱化版本。如果配置单元已启动,此选项中列出的单元也将启动。但是,如果列出的单元启动失败或无法添加到事务中,则不会影响整个事务的有效性。这是将一个单元的启动与另一个单元的启动挂钩的推荐方法。
请注意,也可以通过在单元文件附带的 .wants/ 目录中添加符号链接来在单元配置文件之外配置此类型的依赖项。有关详细信息,请参阅上文。
之前=,之后=
这两个设置需要一个空格分隔的单元名称列表。它们配置单元之间的顺序依赖关系。如果单元 foo.service 包含设置 Before=bar.service 并且两个单元都在启动,bar.service 的启动将延迟到 foo.service 完成启动。请注意,此设置与 Requires=、Wants= 或 BindsTo= 配置的需求依赖关系无关且正交。在 After= 和 Requires= 选项中都包含单元名称是一种常见模式,在这种情况下,列出的单元将在使用这些选项配置的单元之前启动。此选项可以多次指定,在这种情况下将为所有列出的名称创建顺序依赖关系。After= 是 Before= 的逆,即,虽然 After= 确保配置的单元在列出的单元完成启动后启动,但 Before= 确保相反,即配置的单元在列出的单元启动之前完全启动。请注意,当两个具有顺序依赖关系的单元关闭时,将应用启动顺序的逆序。即,如果一个单元在另一个单元上配置了 After=,则如果两者都关闭,则前者会先停止,然后后者停止。给定两个之间存在任何顺序依赖关系的单元,如果一个单元关闭而另一个单元启动,则关闭顺序先于启动。在这种情况下,顺序依赖关系是 After= 还是 Before= 并不重要。关闭两者中的哪一个也不重要,只要一个关闭而另一个启动即可。在所有情况下,关闭顺序都先于启动。如果两个单元之间没有顺序依赖关系,则它们会同时关闭或启动,并且不按顺序排列。单元完成启动的确切时间取决于单元类型。最重要的是,对于服务单元,当所有配置的启动命令都已调用并且它们失败或报告启动成功时,启动才被视为完成,以达到 Before=/After= 的目的。
ExecStartPre=, ExecStartPost=
分别在 ExecStart= 中的命令之前或之后执行的附加命令。语法与 ExecStart= 相同,不同之处在于允许多个命令行并且命令按顺序一个接一个地执行。
如果任何一个命令(不以“-”为前缀)失败,则其余命令将不会执行,并且该单元被视为失败。
仅当所有未以“-”为前缀的 ExecStartPre= 命令成功退出后,ExecStart= 命令才会运行。
ExecStartPost= 命令仅在 ExecStart= 中指定的命令成功调用后运行,由 Type= 确定(例如,对于 Type=simple 或 Type=idle,该进程已启动,对于 Type=oneshot,最后一个 ExecStart= 进程已成功退出,对于 Type=forking,初始进程已成功退出,对于 Type=notify,发送了“READY=1”,或者对于 Type=dbus,已采用 BusName=)。
请注意,ExecStartPre= 不能用于启动长时间运行的进程。通过 ExecStartPre= 调用的进程分叉的所有进程将在下一个服务进程运行之前被终止。
请注意,如果 ExecStartPre=、ExecStart= 或 ExecStartPost= 中指定的任何命令失败(并且没有以“-”为前缀,参见上文)或在服务完全启动之前超时,则将继续执行 ExecStopPost= 中指定的命令,并跳过 ExecStop= 中的命令。
答案2
您应该添加 --after
选项来查看依赖关系。在这种情况下,您的命令将如下所示:
systemctl list-dependencies --after gammu-smsd.service