java:systemd-notify 中不一致的看门狗超时

标签 java systemd

我的 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,但想知道在执行该路线之前是否可以进行简单的配置。

最佳答案

这是解决问题的 JNA 代码:

import com.sun.jna.Library;
import com.sun.jna.Native;

/**
 * The task issues a notification to the systemd watchdog. The systemd watchdog
 * will restart the service if the notification is not received.
 */

public class WatchdogNotifierTask implements Runnable {

private static final String SYSTEMD_SO = "systemd";
private static final String WATCHDOG_READY = "WATCHDOG=1";

@Override
public void run() {

  try {
    int returnCode = SystemD.INSTANCE.sd_notify(0, WATCHDOG_READY);
    if (returnCode < 0) {
      Log.MAIN_LOG.error(
          "Systemd watchdog returned a negative error code: " + Integer.toString(returnCode));
    } else {
      Log.MAIN_LOG.debug("Successfully updated systemd watchdog.");
    }
  } catch (Exception e) {
    Log.MAIN_LOG.error("calling sd_notify native code failed with exception: ", e);
  }
} 

/**
 * This is a linux-specific interface to load the systemd shared library and call the sd_notify
 * function. Should we need other systemd functionality, it can be loaded here. It uses JNA for
 * native library calls.
 *
 */
interface SystemD extends Library {
  SystemD INSTANCE = (SystemD) Native.loadLibrary(SYSTEMD_SO, SystemD.class);
  int sd_notify(int unset_environment, String state);
}

}

关于java:systemd-notify 中不一致的看门狗超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33964315/

相关文章:

java - 如何将我自己的代码/函数和外部java库添加到azure函数应用程序

java - 将 std*** 从 C++ 重定向到 Java 以进行日志记录

go - 我可以根据我正在构建的操作系统导入 Golang 包吗?

amazon-web-services - 启动 ec2 服务器时自动启动 docker

java - 配置 JMX 导出器时 Kafka 无法启动

ruby-on-rails - puma systemd 脚本不启动 puma

java - sax解析器的单元测试

java - java jaxb 是如何工作的?

java - Maven 构建配置文件激活

raspberry-pi - 无法禁用 systemd serial-getty 服务