进一步阅读

进一步阅读

我有一个基于systemd分叉服务的启动脚本(我们称之为)fooYAJSW(另一个 Java 服务包装器)。文件的相关部分.service如下所示:

ExecStart=/opt/foo/startup.sh
ExecStop=/opt/foo/shutdown.sh
Restart=always    
Type=forking
PIDFile=/opt/foo/wrapper.pid

startup.sh脚本负责启动 YAJSW 包装器。设置 YAJSW 配置文件,以便在启动期间将其 PID 写入文件:

 wrapper.pidfile = /opt/foo/wrapper.pid

这样,如果包装器进程终止(出于任何原因),systemd 应该将其启动,这是所需的行为。我已经验证此配置工作正常,但在journalctl中显示了一条奇怪的行:

foo.service: PID file /opt/foo/wrapper.pid not readable (yet?) after start: No such file or directory

奇怪的是,systemctl status foo 正确显示了主 PID:

foo.service
...
Main PID: 12313 (java)

我是否做错了什么,或者这是软件组件之一的错误?我运行的是 Ubuntu 16.04.3 LTS,内核版本 4.4.0,systemd 版本 229.4。任何帮助将不胜感激。

答案1

分叉服务 [...] YAJSW(又一个 Java 服务包装器)[...] ExecStart=/opt/foo/startup.sh[...] ExecStop=/opt/foo/shutdown.sh[...] PID 被写入文件 [...]

这类东西在 Java 中很常见,而且实际上似乎在一般的 Oracle 系统中也很常见;但也完全没有必要。您不需要用 shell 脚本或 Java 编写的 Poor Man 服务管理器在实际的服务管理器下运行。 PID 文件是一种完全危险且不稳定的机制。您不需要startup.sh脚本shutdown.sh,它们最终会将实际的服务流程推向流程树,从而没有好结果。您不需要额外的 YAJSW 配置文件。您不需要基于在内存中缓冲标准输出的复杂且特殊的日志记录机制。

您的服务进程应该由实际服务管理直接管理,并且不会使用 systemd 分叉就绪协议,因为几乎没有任何东西实际上使用它。不要使用包装 shell 脚本来运行 Poor Man 的服务管理器。不要使用 PID 文件。任何 shell 脚本包装器都应该链式加载,而不是 fork。你的配置文件是systemd服务单元文件,而不是一些其他配置文件。您的日志记录机制是服务管理附带的一种机制,它捕获标准输出和标准错误并将其数据写入文件。

进一步阅读

答案2

我不会说这是一个错误,而是一个复杂性问题。您当前拥有此链,只是为了启动和管理您的应用程序:

systemd -> startup.sh -> YAJSW -> actual app

我不知道startup.sh和YAJSW到底在做什么,但最好尝试简化管理:

systemd -> actual app

那么如果管理出现问题的话很多更容易推理发生的事情。

我建议通过最大限度地使用systemd管理工具并最小化或消除脚本和 YAJSW 正在执行的操作来简化情况。

相关内容