检测微服务内部进程的完成情况

时间:2018-04-25 18:45:55

标签: java

我有一个Java微服务器,用于执行程序然后监视stderr,直到没有返回任何内容:

  Process p = Runtime.getRuntime().exec("/bin/sh /var/task/bin/iTMSTransporter " + commandLine);
  BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

  logger.log("StdErr:\n");
  while ((s = stdError.readLine()) != null && p.isAlive()) {
    System.out.println("stderr: " + s);
    if (s.indexOf("DBG-X") == -1) {
      result.stdErr += s + "\n";
    }
  }
  this.logger.log("finished reading stderr\n");

这对于检测外部程序的完成是有效的,并且它始终有效。现在外部程序已经更新,它似乎开始输出stderr但是然后停止(应该更多地去 stderr 流)并最终超时。

然后我添加了p.isAlive()以尝试捕获炮轰程序的完成。这似乎没有任何影响。现在这是令人沮丧的部分...在我的微服务的旧版本中,我使用NodeJS而不是Java来运行该程序。 NodeJS版本仍然可以通过监听close事件来运行:

shell.stdout.on('data', data => {
  stdout += data;
});
shell.stderr.on('data', data => {
  stderr += data;
});
shell.on('error', error => {
  reject(error);
});
shell.on('close', () => {
  resolve({
    stdout: stdout,
    stderr: stderr
  });
});

我能用Java做些什么吗?

----加法-----

我尝试了一些我在网上看过的东西:

  Runtime rt = Runtime.getRuntime();
  rt.addShutdownHook(new Thread(new Runnable() {
    public void run() {
      System.out.println("\nGOT HERE\n");
    }
  }));
  Process p = rt.exec("/bin/sh /var/task/bin/iTMSTransporter " + commandLine);

以为我会在新线程中检测到它并输出“GOT HERE”但从未发送到控制台。

1 个答案:

答案 0 :(得分:1)

如果您只是想等待该过程完成,waitFor应该是合适的。

Process p = Runtime.getRuntime().exec("/bin/sh /var/task/bin/iTMSTransporter " + commandLine);
try {
    p.waitFor();
    // now, the process has terminated
} catch (InterruptedException e) {
    // something went wrong
    e.printStackTrace();
}

如果您确实希望捕获out-err-stream,那实际上有点复杂,因为您需要为此创建新线程(不是那个问题,而是一个很大的问题,但是如果您只是想知道该过程已经完成,那就是OTT。

也许可以看process.waitFor() never returns