繁体   English   中英

运行时 exec 进程挂起

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM