2012-12-17 79 views
0

我正在嘗試使用Hadoop IPC在IPC之間創建一個簡單的父子進程。事實證明,程序執行並打印結果,但不會退出。這是它的代碼。Hadoop RPC服務器不會停止

interface Protocol extends VersionedProtocol{ 
    public static final long versionID = 1L; 
    IntWritable getInput(); 
} 

public final class JavaProcess implements Protocol{ 
    Server server; 

    public JavaProcess() { 
    String rpcAddr = "localhost"; 
    int rpcPort = 8989; 
    Configuration conf = new Configuration(); 
    try { 
    server = RPC.getServer(this, rpcAddr, rpcPort, conf); 
    server.start(); 

    } catch (IOException e) { 
    e.printStackTrace(); 
    } 
} 

public int exec(Class klass) throws IOException,InterruptedException { 
    String javaHome = System.getProperty("java.home"); 
    String javaBin = javaHome + 
     File.separator + "bin" + 
     File.separator + "java"; 
    String classpath = System.getProperty("java.class.path"); 
    String className = klass.getCanonicalName(); 

    ProcessBuilder builder = new ProcessBuilder(
     javaBin, "-cp", classpath, className); 

    Process process = builder.start(); 
    int exit_code = process.waitFor(); 
    server.stop(); 

    System.out.println("completed process"); 
    return exit_code; 
} 

public static void main(String...args) throws IOException, InterruptedException{ 
    int status = new JavaProcess().exec(JavaProcessChild.class); 
    System.out.println(status); 
} 

@Override 
public IntWritable getInput() { 
    return new IntWritable(10); 
} 

@Override 
public long getProtocolVersion(String paramString, long paramLong) 
    throws IOException { 
    return Protocol.versionID; 
} 
} 

這裏是子進程類。不過我已經意識到這是由於服務器端的RPC.getServer()導致它的罪魁禍首。這是一些已知的hadoop錯誤,或者我失去了一些東西?

public class JavaProcessChild{ 

    public static void main(String...args){ 
    Protocol umbilical = null; 
    try { 
     Configuration defaultConf = new Configuration(); 
     InetSocketAddress addr = new InetSocketAddress("localhost", 8989); 
     umbilical = (Protocol) RPC.waitForProxy(Protocol.class, Protocol.versionID, 
      addr, defaultConf); 
     IntWritable input = umbilical.getInput(); 

     JavaProcessChild my = new JavaProcessChild(); 

     if(input!=null && input.equals(new IntWritable(10))){ 
     Thread.sleep(10000); 
     } 
     else{ 
     Thread.sleep(1000); 
     } 
    } catch (Throwable e) { 
     e.printStackTrace(); 
    } finally{ 
     if(umbilical != null){ 
     RPC.stopProxy(umbilical); 
     } 
    } 
} 
} 

回答

1

我們通過郵件對此進行了整理。但我只想給我兩毛錢給公衆:

因此,不死在那裏的線程(因此不讓主線程完成)是org.apache.hadoop.ipc.Server$Reader。 原因是,readSelector.select();的執行是不可中斷的。如果仔細觀察調試器或線程轉儲,即使主線程已被清理,它也會永遠等待該調用。

兩個可能的解決方法:

  • 使讀者線程一個守護進程(不是很爽,因爲選擇 不會正確地清理,但這一過程將結束)
  • 明確地關閉「 readSelector「,當中斷線程池時

但是,這是Hadoop中的一個錯誤,我沒有時間查看JIRA。也許這已經是固定的,在YARN,舊的IPC被protobuf和節儉取代。

順便說一句,這也是平臺依賴於選擇器的實現,我在debian/windows系統上觀察過這些殭屍,但在redhat/solaris上沒有。

如果有人對Hadoop 1.0補丁感興趣,請給我發電子郵件。我將在不久的將來梳理JIRA錯誤,並在此處編輯更多信息。 (無論如何,這可能是固定的)。