我正在开发一个应用程序,以便从spark
应用程序执行java
批处理应用程序。
有一个主类启动线程来启动spark
应用程序。它使用zookeeper
在启动leader
应用程序的计算机中查找spark
。 Main
方法如下所示:
public static void main(String[] args) throws IOException {
final int id = Integer.valueOf(args[0]);
final String zkURL = args[1];
final ExecutorService service = Executors.newSingleThreadExecutor();
final Future<?> status = service.submit(new ProcessNode(id, zkURL));
try {
status.get();
} catch (InterruptedException | ExecutionException e) {
LOG.fatal(e.getMessage(), e);
service.shutdown();
}
选择leader
后,将在其上运行以下代码以启动spark
应用程序。
protected Boolean executeCommand() {
try {
final Runtime rt = Runtime.getRuntime();
final Process proc = rt.exec("sh start-sparkapp.sh");
final int exitVal = proc.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null) {
System.out.println(line);
}
System.out.println(" commandToExecute exited with code: " + exitVal);
proc.destroy();
} catch (final Exception e) {
System.out.println("Exception occurred while Launching process : " + e.getMessage());
return Boolean.FALSE;
}
return Boolean.TRUE;
}
但是这会启动一个长期运行的spark
工作。所以我相信,只有在spark
作业完成时才会执行下一部分代码。我的要求是,一旦spark
应用程序启动,控件就转到下一部分代码,我在那里监视同一spark
应用程序的状态。即我启动spark
应用程序并监视来自同一spark
应用程序的java
应用程序的状态。
假设我有一个监视应用程序状态的方法montior
public String monitor(ApplicationId id)
有任何建议如何实现这一目标?
答案 0 :(得分:0)
由于您将使用方法public String monitor(ApplicationId id)
监视Spark应用程序,因此我假设您不希望当前线程使用proc.waitFor()
等待该进程。此外,您不希望将进程的正常输出打印到控制台。这两个操作都会使您的线程在生成的进程上等待。此外,您的monitor方法应该将生成的进程的进程ID,而不是spark applicationId作为输入。
因此修改后的代码可能如下所示:
protected Boolean executeCommand() {
try {
final Runtime rt = Runtime.getRuntime();
final Process proc = rt.exec("sh start-sparkapp.sh");
/*
*Call to method monitor(ProcessId id)
*/
} catch (final Exception e) {
System.out.println("Exception occurred while Launching process : " + e.getMessage());
return Boolean.FALSE;
}
return Boolean.TRUE;
}