在構建服務器上運行phatomjs/java集成測試後,phantomjs進程仍然在後臺運行,必須手動終止。如何在測試完成後殺死在後臺運行的phantomjs進程
有沒有辦法在java代碼中做到這一點?我已經在測試清理部分使用了driver.quit()。還有什麼還包括在內?
在構建服務器上運行phatomjs/java集成測試後,phantomjs進程仍然在後臺運行,必須手動終止。如何在測試完成後殺死在後臺運行的phantomjs進程
有沒有辦法在java代碼中做到這一點?我已經在測試清理部分使用了driver.quit()。還有什麼還包括在內?
這是一個著名的問題,存在的,因爲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");
}
我希望這將有幫助
最簡單的方法(不一定是正式的方式)要殺死他的進程來處理這個問題是要拍
ps -ef | grep phantomjs | awk '{print $2}' | xargs sudo kill -9
在終端上運行會殺死所有後臺以上腳本phantomjs你使用Java或Python或Ruby ... 是否已經開始他們一個快速的解決方法,直到:從bash腳本,終止所有phantomjs進程kill命令實際的錯誤得到解決了,imo。
正是我在找什麼 - 謝謝。 – 2016-11-30 10:48:57
這個整個shell管道可以被'killall -s SIGKILL phantomjs'或甚至'killall phantomjs'替代(如果SIGTERM足夠了) – 2017-05-24 19:30:13
@WorryNerd你的phantomjs的版本是什麼? – erhun 2015-02-11 22:48:59
類似的問題要求爲phyton http://stackoverflow.com/questions/25110624/how-to-properly-stop-phantomjs-execution有一個工作在這裏爲Linux系統手動過程pgrep phantomjs | xargs kill – erhun 2015-02-11 22:55:28
感謝@erhun重定向到這個問題。那是我目前面臨的問題,但我無法每次手動殺死這些進程。我在我的代碼中使用了driver.quit(),但是一旦構建完成,這些進程仍留在服務器中。是否有任何線程談到在teamcity中添加一個步驟來殺死進程? – WorryNerd 2015-02-12 17:42:35