2015-02-11 136 views
3

在構建服務器上運行phatomjs/java集成測試後,phantomjs進程仍然在後臺運行,必須手動終止。如何在測試完成後殺死在後臺運行的phantomjs進程

有沒有辦法在java代碼中做到這一點?我已經在測試清理部分使用了driver.quit()。還有什麼還包括在內?

+0

@WorryNerd你的phantomjs的版本是什麼? – erhun 2015-02-11 22:48:59

+0

類似的問題要求爲phyton http://stackoverflow.com/questions/25110624/how-to-properly-stop-phantomjs-execution有一個工作在這裏爲Linux系統手動過程pgrep phantomjs | xargs kill – erhun 2015-02-11 22:55:28

+0

感謝@erhun重定向到這個問題。那是我目前面臨的問題,但我無法每次手動殺死這些進程。我在我的代碼中使用了driver.quit(),但是一旦構建完成,這些進程仍留在服務器中。是否有任何線程談到在teamcity中添加一個步驟來殺死進程? – WorryNerd 2015-02-12 17:42:35

回答

0

這是一個著名的問題,存在的,因爲2012年12月 - UnreachableBrowserException

所以,我提出了一些解決方法 - 創建類,這與重載方法擴展PhantomJSDriver「執行」:

@Override 
protected Response execute(String driverCommand, Map<String, ?> parameters) { 
    int retryAttempt = 0; 

    while (true) { 
     try { 
      return super.execute(driverCommand, parameters); 
     } catch (WebDriverException e) { 
      retryAttempt++; 
      if (retryAttempt > retryCount) { 
       throw e; 
      } 
     } 
    } 
} 

這是有幫助的,但並不總是 - 有時phantomjs過程沒有停止工作。所以,我發現了一種通過PID(進程ID)

@Override 
protected Response execute(String driverCommand, Map<String, ?> parameters) { 
    int retryAttempt = 0; 

    while (true) { 
     try { 
      return super.execute(driverCommand, parameters); 
     } catch (WebDriverException e) { 
      retryAttempt++; 
      if (retryAttempt > retryCount) { 
       if(driverCommand.equalsIgnoreCase("quit")) { 
        int port = GetDriverPort(); 
        try { 
         int processID = GetPIDByServerPort(port); 
         boolean processExist = processID != -1; 
         if(processExist) { 
          log.info("Killing phantomJS, of process id:" + processID + " that listen to port:" + port); 
          KillPhantomProcess(processID); 
         } 
         return null; 
        } catch (IOException | InterruptedException ignore) { 
         throw e; 
        } 
       } 

       throw e; 
      } 
     } 
    } 
} 

private int GetDriverPort(){ 
    return ((HttpCommandExecutor)(this).getCommandExecutor()).getAddressOfRemoteServer().getPort(); 
} 

private int GetPIDByServerPort(int port) throws InterruptedException, IOException { 
    int pid = -1; 
    ProcessBuilder p = new ProcessBuilder("cmd.exe", "/C", "netstat -no | findstr :" + String.valueOf(port)); 
    p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE); 

    Process netstat = p.start(); 
    netstat.waitFor(); 
    InputStream inputStream = netstat.getInputStream(); 

    int bytesRead; 
    byte[] bytes = new byte[1024]; 
    String result = ""; 
    while ((bytesRead = inputStream.read(bytes)) > -1) { 
     result = result + new String(bytes, 0, bytesRead); 
    } 

    String[] lines = result.split("\\n+"); 
    for (String line : lines) { 
     if(!(line.toUpperCase().contains("ESTABLISHED") && line.contains("127.0.0.1:" + port))) continue; 

     String[] str = line.trim().split("\\s+"); 
     if(str[1].contains(String.valueOf(port))) pid = Integer.parseInt(str[4]); 
    } 

    return pid; 
} 

private void KillPhantomProcess(int pid) throws IOException { 
    try { 
     Runtime.getRuntime().exec(TASKKILL_COMMAND + pid); 
    } catch (IOException e) { 
     log.error("Failed to kill phantomJs process. PID: " + pid, e); 
     throw e; 
    } 

    if(pid > 0) log.info("phantomJs process " + pid + " was interrupted"); 
} 

我希望這將有幫助

7

最簡單的方法(不一定是正式的方式)要殺死他的進程來處理這個問題是要拍

ps -ef | grep phantomjs | awk '{print $2}' | xargs sudo kill -9 

在終端上運行會殺死所有後臺以上腳本phantomjs你使用Java或Python或Ruby ... 是否已經開始他們一個快速的解決方法,直到:從bash腳本,終止所有phantomjs進程kill命令實際的錯誤得到解決了,imo。

+1

正是我在找什麼 - 謝謝。 – 2016-11-30 10:48:57

+3

這個整個shell管道可以被'killall -s SIGKILL phantomjs'或甚至'killall phantomjs'替代(如果SIGTERM足夠了) – 2017-05-24 19:30:13

相關問題