运行时执行进程挂起

huangapple go评论77阅读模式
英文:

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 提供了一个应用程序中所有Pod的日志流,这些通过颜色和Pod名称进行标识。

谢谢。

英文:

I'm trying to make a javafx application which displays the logs from kubernetes. I'm using Runtime.getRuntime().exec to get the output of kubetail servicename in the following way:

 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();
        }

The process starts normally and I see "Will tail 2 pods...". The problem appears when I make a request on that service and a lot of logs appears. The service returns a report and this report is archived and it is also logged. The report is quite big, 40K characters. The tail somehow hangs in the middle of the logged report and I don't get any more data, but if I send another request, it continues from where it hanged and stops again on the report of the second request.

I tried using buffered reader and also wrapped the inputstream with NIO, but the problem persist. I also tried to use kubectl logs and this works on but I don't have any identification for the line of log (I don't know which pod it belongs to). kubetail gives a stream of logs for all the pods in an application and these are identified by color and by pod name.

Thank you

答案1

得分: 1

你没有正确地消耗标准输出和标准错误流,如果其中一个流填满而您没有读取,将会导致进程输出挂起。在使用 ProcessBuilder 时,您可以尝试将标准错误重定向到标准输出流:

ProcessBuilder pb = new ProcessBuilder(new String[]{"kubetail", "serviceName"});
pb.redirectErrorStream(true);
Process exec = pb.start();
... 您的读取代码
int rc = exec.waitFor();

或者:添加线程来消耗标准输出和标准错误流:

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);
    }
}
英文:

You are not consuming the stdout and stderr streams properly, they will cause process output to hang if one fills without you reading it. You could try setting stderr to go to stdout class when using ProcessBuilder

ProcessBuilder pb = new ProcessBuilder(new String[]{"kubetail", "serviceName"});
pb.redirectErrorStream(true);
Process exec = pb.start();
... Your reading code
int rc = exec.waitFor();

OR: add threads to consume both stdout and stderr streams:

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();

with method:

static void copy(InputStream in, OutputStream out)
{
    try(var autoClose = in; var autoClose2 = out)
    {
        in.transferTo(out);
    }
    catch(IOException io)
    {
        throw new UncheckedIOException(io);
    }
}

huangapple
  • 本文由 发表于 2020年10月20日 15:28:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/64440436.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定