【发布时间】:2015-11-27 20:16:19
【问题描述】:
我的 java 应用程序安装在 OpenSUSE 13.2 操作系统上,并且我使用 systemd 进行进程控制。 (系统版本 210)
我想通过 systemd-notify 来利用 systemd 看门狗功能。但是,我注意到由于看门狗的超时时间不一致,应用程序重新启动。
如果 WatchdogSec=120,并且应用程序配置为每 60 秒调用一次 systemd-notify,我观察到平均每 5 到 20 分钟重新启动一次。
这里是该进程的(略微编辑的)systemd 单元文件:
# Cool systemd service
[Unit]
Description=Something Awesome
After=awesomeparent.service
Requires=awesomeparent.service
[Service]
Type=simple
WorkingDirectory=/opt/awesome
Environment="AWESOME_HOME=/opt/awesome"
User=awesomeuser
Restart=always
WatchdogSec=120
NotifyAccess=all
ExecStart=/home/awesome/jre1.8.0_05/bin/java -jar awesome.jar
[Install]
WantedBy=multi-user.target
这里是调用 systemd-notify 的代码
String pidStr = ManagementFactory.getRuntimeMXBean().getName();
pidStr = pidStr.split("@")[0];
String cmd = "/usr/bin/systemd-notify";
Process process = new ProcessBuilder(cmd,
"MAINPID=" + pidStr,
"WATCHDOG=1").redirectErrorStream(true)
.start();
int exitCode = 0;
if ((exitCode = process.waitFor()) != 0) {
String output = IOUtils.toString(process.getInputStream());
Log.MAIN_LOG.error("Failed to notify systemd: " +
((output.isEmpty()) ? "" : " " + output) +
" Exit code: " + exitCode);
}
在日志中,我从未看到失败消息(进程总是返回 0 退出代码),并且我 100% 确定任务每分钟每分钟执行一次。我可以看到任务日志在重新启动之前立即执行。
有人知道为什么 systemd-notify 有时不起作用吗?
我正在考虑编写代码以直接调用 sd_pid_notify,但想知道在走这条路线之前是否可以做一个简单的配置。
【问题讨论】:
-
您是否尝试过使用JNI 调用sd_notify(3)?因此,您可以更准确地检查呼叫状态。我想Java守护程序和systemd之间的调用存在一些问题。此外,我会在
ProcessBuilder.start()之前立即记录一条消息,并在systemd-notify上使用日志记录外壳包装器,以确保及时执行子进程的调用并且没有任何不可预测的延迟 -
我对 CentOS7.0 (systemd 208) 也有类似的问题。我有同样的 2 分钟看门狗时间,今天它失败了(似乎是随机的)。就我而言,我每秒直接调用一次
sd_notify()。我没有任何迹象表明发送通知的过程完全停止了。 -
我最终为此使用了 JNA,从那以后它就一直坚如磐石。我将在下面的答案中发布代码。