[英]Runtime exec Process hangs
我正在尝试制作一个 javafx 应用程序,它显示来自 kubernetes 的日志。 我正在使用Runtime.getRuntime().exec
通过以下方式获取kubetail servicename
的输出:
Process exec = Runtime.getRuntime().exec(new String[]{"kubetail", "serviceName"});
InputStream inputStream = exec.getInputStream();
int read;
try {
while (((read = inputStream.read()) != -1)) {
System.out.print((char) read);
}
} catch (IOException e) {
e.printStackTrace();
}
该过程正常启动,我看到“Will tail 2 pods...”。 当我对该服务提出请求并出现大量日志时,就会出现问题。 该服务返回一个报告,该报告被存档并被记录。 报告相当大,40K 个字符。 尾部不知何故挂在记录的报告中间,我没有得到更多数据,但是如果我发送另一个请求,它会从挂起的地方继续,并在第二个请求的报告上再次停止。
我尝试使用缓冲读取器并用 NIO 包装输入流,但问题仍然存在。 我也尝试使用kubectl logs
,这有效,但我没有任何日志行的标识(我不知道它属于哪个 pod)。 kubetail
为应用程序中的所有kubetail
提供日志流,这些日志通过颜色和 pod 名称进行标识。
谢谢
您没有正确使用 stdout 和 stderr 流,如果在没有您阅读它的情况下填充,它们将导致进程输出挂起。 您可以尝试在使用ProcessBuilder
时将 stderr 设置为转到 stdout 类
ProcessBuilder pb = new ProcessBuilder(new String[]{"kubetail", "serviceName"});
pb.redirectErrorStream(true);
Process exec = pb.start();
... Your reading code
int rc = exec.waitFor();
或:添加线程以同时使用 stdout 和 stderr 流:
Process exec = Runtime.getRuntime().exec(new String[]{"kubetail", "serviceName"});
new Thread(() -> copy(exec.getInputStream(), System.out), "STDOUT").start();
new Thread(() -> copy(exec.getErrorStream(), System.err), "STDERR").start();
int rc = exec.waitFor();
用方法:
static void copy(InputStream in, OutputStream out)
{
try(var autoClose = in; var autoClose2 = out)
{
in.transferTo(out);
}
catch(IOException io)
{
throw new UncheckedIOException(io);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.