背景
Java外调程序,比如frp、进行服务监听,然后保活,如果挂掉,不断拉起等操作
Show Code
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExecCmdResult {
private boolean status;
private int exitCode;
private String execCommand;
private String execContent;
private Long cost;
}
import com.boommanpro.marriott.helper.model.ExecCmdResult;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ExecCmdUtils {
private final static int BUFFER_SIZE = 1024;
private final static String DEFAULT_ENCODING = "gbk";
private static class ProcessWorker extends Thread {
private final Process process;
private volatile int exitCode = -99;
private volatile boolean completed = false;
private volatile String output = "";
private ProcessWorker(Process process) {
this.process = process;
}
@Override
public void run() {
try (InputStreamReader reader = new InputStreamReader(
process.getInputStream(), DEFAULT_ENCODING)) {
StringBuilder log = new StringBuilder();
char[] buffer = new char[BUFFER_SIZE];
int length;
while ((length = reader.read(buffer)) != -1) {
log.append(buffer, 0, length);
}
output = log.toString();
exitCode = process.waitFor();
completed = true;
} catch (InterruptedException | IOException e) {
Thread.currentThread().interrupt();
}
}
public int getExitCode() {
return exitCode;
}
public String getOutput() {
return output;
}
public boolean isCompleted() {
return completed;
}
}
public static ExecCmdResult execCmd(String command) {
return execCmd(command, 15);
}
public static void execDaemonCmd(String command) {
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
// 合并错误输出流
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
InputStreamReader reader = new InputStreamReader(process.getInputStream(), DEFAULT_ENCODING);
char[] buffer = new char[BUFFER_SIZE];
int length;
while ((length = reader.read(buffer)) != -1) {
log.info("command:{},rowOutput:\n{}", command, new String(buffer, 0, length));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
throw new RuntimeException("run error");
}
public static ExecCmdResult execCmd(String command, int timeoutSecond) {
long start = System.currentTimeMillis();
StringBuilder content = new StringBuilder();
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
// 合并错误输出流
processBuilder.redirectErrorStream(true);
Process process;
try {
process = processBuilder.start();
} catch (IOException e) {
log.error("execCmd error, execCmd:{}.e:", command, e);
return new ExecCmdResult(false, -1, command, e.getMessage(), System.currentTimeMillis() - start);
}
ProcessWorker processWorker = new ProcessWorker(process);
int exitCode = processWorker.getExitCode();
processWorker.start();
try {
processWorker.join(TimeUnit.SECONDS.toMillis(timeoutSecond));
if (processWorker.isCompleted()) {
content.append(processWorker.getOutput());
exitCode = processWorker.getExitCode();
} else {
process.destroy();
processWorker.interrupt();
return new ExecCmdResult(false, processWorker.exitCode, "thread exec timeout", processWorker.getOutput(), System.currentTimeMillis() - start);
}
} catch (InterruptedException e) {
processWorker.interrupt();
}
return new ExecCmdResult(exitCode == 0, exitCode, command, content.toString(), System.currentTimeMillis() - start);
}
}