进一步阅读

进一步阅读

我有一个服务,我想通过 systemd 来管理 - 我们称之为它foo。我编写了单元文件,它们工作得很好。因此,如果我运行systemctl start foo,服务会正确启动,并且我可以使用 来查看其状态systemctl status foo

但是,外部程序也可以启动该服务,并且它不使用 systemd 来启动该服务。因此,该服务可以运行,但由于它不是通过 systemd 启动的,因此 systemd 不知道它。在这种情况下,systemctl status foo即使服务运行正常,也会报告服务失败。

有没有办法让 systemd “继承”或“采用”此服务,以便systemctl status foo正确报告该服务正在运行,即使 systemd 没有启动它?使用 SysV,我会编写一个小的“状态”脚本,这样我就可以/etc/init.d/foo status,但这似乎不适合 systemd 模型。

需要明确的是,当外部程序启动服务时,该服务的进程仍然是 PID 1/systemd 的子进程。但是,systemd 不会将它们识别为 service 的一部分foo,因为 systemd 没有启动并注册它们。

具体技术有:

  • Oracle WebLogic(该服务是托管 WebLogic 实例)
  • Oracle NodeManager(这是也可能启动服务的外部程序)
  • 系统219

答案1

不会。就 systemd 而言,该进程将在不同的上下文中运行。

事实上,这是应避免桌面总线服务激活的原因之一。就 systemd 而言,由桌面总线代理直接生成的服务进程是其服务的一部分。

人们可以使用适当的权限在控制组之间移动进程。但这只是工作的一半,而另一半,即让 systemd 相信它在没有启动一个单元的情况下启动了一个单元,并重写其内部数据结构的必要部分,则没有提供。

这不仅不是 systemd 的模型,也不是大多数服务管理子系统的模型。

顺便说一句,太多人对 Oracle 软件的“还不错”服务单位实际上并不是这样,而是在恐怖之屋领土。

进一步阅读

答案2

简而言之,除非服务是由 systemd 本身启动的,否则没有办法让 systemd 考虑启动该服务。 systemd 的要点之一是管理服务的一致性,而采用不同的方式来启动服务则违背了这一想法。

现在,系统有一项规定可以管理外部启动的流程,这似乎有点适合您描述的情况。这实际上是一种单独的单位,一个范围单位

使用作用域单元仍然需要外部系统与 systemd 交互,因为作用域单元只能通过对 systemd 的 D-Bus 请求来启动,其中传递 PID,用作作用域中的初始进程。此外,当启动作用域单元时,systemd 仍然希望自己创建 cgroup(然后它将传递的 PID 移动到创建的 cgroup 中)。因此,如果希望 systemd 管理这些进程,则需要创建新进程的应用程序的支持作为一个范围。

简而言之,避免使用两种不同的方式来启动服务。如果您需要使用第三方服务管理器,请仅使用它。

如果您要解决的问题是在启动过程中启动服务,那么:

  1. 检查您的第三方管理器(在您的情况下为 Oracle NodeManager)是否支持在启动期间配置服务。由于它管理服务,因此它也应该在启动期间管理服务。

  2. 如果您涉及 systemd,则使用一个简单的oneshot服务单元,只需请求第三方管理器启动服务即可。这意味着通过某种 API 或 RPC(可能通过 HTTP)联系第三方管理器(在您的例子中为 Oracle NodeManager),并告诉它启动服务。

如果您使用 systemdoneshot进行启动,请适当地命名您的单元(例如“start-foo”或“initial-foo”或“foo-startup”)以明确它不会保持“启动”状态,并保持RemainAfterExit=no(默认值),因此检查该单元的状态只会表明它已成功完成,因此不会混淆它反映了在第三方管理器下运行的服务的状态。

相关内容