0

我写了一个小程序来启动 Hive Server。启动 Hive 服务器的命令在 shell 文件中。当我调用 shell 文件来启动 Hive Server 时,它往往会启动它并挂起。程序有问题吗?

代码:

            try
        {
            String cmd = "/home/hadoop/sqoop-1.3.0-cdh3u1/bin/StartServer.sh"; // this is the command to execute in the Unix shell

            // create a process for the shell
            ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
            pb.redirectErrorStream(true); // use this to capture messages sent to stderr
            Process shell = pb.start();
            InputStream shellIn = shell.getInputStream(); // this captures the output from the command
            // wait for the shell to finish and get the return code
            // at this point you can process the output issued by the command

            // for instance, this reads the output and writes it to System.out:
            int c;
            while ((c = shellIn.read()) != -1) 
            {
                System.out.write(c);
            }

            // close the stream
            shellIn.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
            e.printStackTrace(pw);
            pw.flush();
            System.exit(1);
        }

请让我知道这一点。我在程序中错过了什么吗?

谢谢。

4

2 回答 2

2

看起来你的程序正在做你告诉它做的事情。

前几行确实应该启动 Hive 服务器。之后的行从服务器进程的标准输出中读取,并将每个字符回显到 Java 进程的控制台。只要 Hive 服务器的输出流存在,您的 Java 进程就会处于一个循环中(进行阻塞 I/O 调用)。

也就是说,只要 Hive 服务器正在运行,您的 Java 进程就会处于循环中,回显输出。

这是你想要它做的吗?如果是这样,那么它显然将无法退出。如果没有,那么您根本没有理由从服务器的输入流中读取数据,并且您的 Java 程序可以在启动服务器进程后退出。或者,如果您想在 Java 进程中侦听输出执行其他操作,则需要使用多个线程才能同时执行两项操作。

于 2012-05-03T10:45:32.120 回答
1

据我所知,您正在启动服务器,即启动并且不会很快终止的应用程序。它仍在运行。这意味着此应用程序(服务器)的 STDOUT 未关闭(除非您正在终止服务器)。

方法shellIn.read()是阻塞。它从输入流中读取下一个字节,并在读取字节或关闭流时返回。

因此,在您的情况下,流永远不会关闭,因此您的程序卡住了:它永远等待输入(并且可能正在读取它)。

要解决此问题,您需要单独的线程:在 java 或 OS 中。您可以从单独的 java 线程运行服务器或编写命令行以在后台运行服务器(例如使用尾随 &)。

于 2012-05-03T10:45:19.403 回答