From 3f220825bc718eb6d894691898782e00e14c6365 Mon Sep 17 00:00:00 2001 From: linbin <495561397@qq.com> Date: Tue, 17 Sep 2024 23:28:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=96=87=E4=BB=B6=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E5=AE=8C=E6=AF=95=E5=90=8E=E5=90=AF=E5=8A=A8=20jar=20?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/tianhe/agent/PlatformHelper.java | 132 +++++++++++++++++ .../tianhe/agent/control/CommandHandler.java | 137 ++---------------- .../agent/control/DownloadFileHandler.java | 8 +- .../org/tianhe/common/command/Command.java | 8 +- .../common/command/impl/UpdateZipVersion.java | 21 +++ 5 files changed, 172 insertions(+), 134 deletions(-) create mode 100644 src/main/java/org/tianhe/agent/PlatformHelper.java create mode 100644 src/main/java/org/tianhe/common/command/impl/UpdateZipVersion.java diff --git a/src/main/java/org/tianhe/agent/PlatformHelper.java b/src/main/java/org/tianhe/agent/PlatformHelper.java new file mode 100644 index 0000000..ae7e24c --- /dev/null +++ b/src/main/java/org/tianhe/agent/PlatformHelper.java @@ -0,0 +1,132 @@ +package org.tianhe.agent; + +import com.jfirer.baseutil.STR; +import com.jfirer.baseutil.StringUtil; +import com.jfirer.jnet.common.api.Pipeline; +import lombok.extern.slf4j.Slf4j; +import org.tianhe.common.packet.LogReport; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; + +import static org.tianhe.agent.AgentConfig.*; + +@Slf4j +public class PlatformHelper +{ + public static List getPidByName(String appName, Pipeline pipeline) + { + List list = new ArrayList<>(); + ProcessBuilder processBuilder = AgentConfig.WINDOW ?// + new ProcessBuilder("cmd.exe", "/c", "wmic process where \"name='java.exe' and CommandLine like '%%" + appName + "%%'\" get ProcessId /value | findstr \"=\"")// + : new ProcessBuilder("sh", "-c", "ps aux | grep " + appName + " | grep -v grep | awk '{print $2}'"); + try + { + Process process = processBuilder.start(); + try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) + { + String line; + while ((line = input.readLine()) != null) + { + log.debug("命令输出:{}", line); + if (StringUtil.isNotBlank(line)) + { + String pid = WINDOW ? line.substring(10) : line; + if (!PID.equalsIgnoreCase(pid)) + { + list.add(pid); + } + } + } + } + process.destroy(); + String msg = list.isEmpty() ? STR.format("通过应用名称:{}检查,未能发现进程", appName) : STR.format("通过应用名称:{}查询,一共发现 PID:{}", appName, String.join(",", list)); + log.debug(msg); + pipeline.fireWrite(new LogReport().setContent(msg)); + return list; + } + catch (Throwable e) + { + log.error("通过应用名称:{}获取应用出现异常", appName, e); + pipeline.fireWrite(new LogReport().setContent(STR.format("通过应用名称:{}获取应用出现异常。异常信息:{}", appName, e))); + return list; + } + } + + public static void killPid(String pid, Pipeline pipeline) + { + ProcessBuilder builder = WINDOW ? new ProcessBuilder("cmd.exe", "/C", "taskkill /F /PID " + pid) : new ProcessBuilder("kill", "-9", pid); + try + { + Process process = builder.start(); + process.waitFor(); + process.destroy(); + String msg = STR.format("终止进程:{}", pid); + log.debug(msg); + pipeline.fireWrite(new LogReport().setContent(msg)); + } + catch (Throwable e) + { + log.error("终止进程:{}出现异常", pid, e); + pipeline.fireWrite(new LogReport().setContent(STR.format("终止进程:{}出现异常。异常信息:{}", pid, e))); + } + } + + public static void startJar(String relativePath, Pipeline pipeline) + { + File targetJarFile = new File(DIR_PATH, relativePath); + if (!targetJarFile.exists()) + { + pipeline.fireWrite(new LogReport().setContent(STR.format("文件:{}不存在,无法启动对应的 jar", targetJarFile.getAbsolutePath()))); + return; + } + String fileName = targetJarFile.getName(); + int index = fileName.lastIndexOf("."); + String fileNameWithoutExtension = fileName.substring(0, index); + String extension = fileName.substring(index); + File copyFile = new File(targetJarFile.getParentFile(), fileNameWithoutExtension + "_copy" + extension); + try + { + Files.copy(targetJarFile.toPath(), copyFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + catch (Throwable e) + { + pipeline.fireWrite(new LogReport().setContent(STR.format("复制文件:{}失败,异常信息:{}", copyFile.getAbsolutePath(), e))); + return; + } + pipeline.fireWrite(new LogReport().setContent(STR.format("复制文件:{}成功,现在准备启动", copyFile.getAbsolutePath()))); + ProcessBuilder builder = WINDOW ? new ProcessBuilder("java", "-jar", copyFile.getAbsolutePath()) : new ProcessBuilder("nohup", "java", "-jar", copyFile.getAbsolutePath(), "&"); + new Thread(() -> { + Process process = null; + try + { + process = builder.start(); + try (BufferedReader reader = process.inputReader(StandardCharsets.UTF_8)) + { + while (reader.readLine() != null) + { + ; + } + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + finally + { + if (process != null) + { + process.destroy(); + } + } + }).start(); + } +} diff --git a/src/main/java/org/tianhe/agent/control/CommandHandler.java b/src/main/java/org/tianhe/agent/control/CommandHandler.java index 81d7edb..ab703f6 100644 --- a/src/main/java/org/tianhe/agent/control/CommandHandler.java +++ b/src/main/java/org/tianhe/agent/control/CommandHandler.java @@ -1,12 +1,11 @@ package org.tianhe.agent.control; import com.jfirer.baseutil.STR; -import com.jfirer.baseutil.StringUtil; import com.jfirer.jnet.common.api.Pipeline; import com.jfirer.jnet.common.api.ReadProcessor; import com.jfirer.jnet.common.api.ReadProcessorNode; import lombok.extern.slf4j.Slf4j; -import org.tianhe.agent.AgentConfig; +import org.tianhe.agent.PlatformHelper; import org.tianhe.common.command.Command; import org.tianhe.common.command.impl.ReBootJar; import org.tianhe.common.command.impl.StopJar; @@ -16,18 +15,8 @@ import org.tianhe.common.packet.ExecuteCommandReq; import org.tianhe.common.packet.FileInfoReq; import org.tianhe.common.packet.LogReport; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; import java.util.List; -import static org.tianhe.agent.AgentConfig.*; - @Slf4j public class CommandHandler implements ReadProcessor { @@ -63,6 +52,9 @@ public class CommandHandler implements ReadProcessor next.pipeline().channelContext().setAttach(new FileDownload(updateJarVersionAndReboot)); next.pipeline().fireWrite(new FileInfoReq().setFileId(updateJarVersionAndReboot.getFileId())); } + case Command.UPDATE_ZIP_VERSION -> + { + } } } else @@ -71,15 +63,15 @@ public class CommandHandler implements ReadProcessor } } - private void rebootJar(ReBootJar reBootJar, Pipeline pipeline) + public static void rebootJar(ReBootJar reBootJar, Pipeline pipeline) { String msg = STR.format("收到重启指令,应用名称:{},文件地址为:{}", reBootJar.getJarNameWithoutExtension(), reBootJar.getRelativePath()); log.debug(msg); LogReport logReport = new LogReport().setContent(msg); pipeline.fireWrite(logReport); - List pidByName = getPidByName(reBootJar.getJarNameWithoutExtension(), pipeline); - pidByName.forEach(pid -> killPid(pid, pipeline)); - startJar(reBootJar.getRelativePath(), pipeline); + List pidByName = PlatformHelper.getPidByName(reBootJar.getJarNameWithoutExtension(), pipeline); + pidByName.forEach(pid -> PlatformHelper.killPid(pid, pipeline)); + PlatformHelper.startJar(reBootJar.getRelativePath(), pipeline); } private void stopJar(StopJar stopJar, Pipeline pipeline) @@ -88,116 +80,7 @@ public class CommandHandler implements ReadProcessor log.debug(msg); LogReport logReport = new LogReport().setContent(msg); pipeline.fireWrite(logReport); - List pidByName = getPidByName(stopJar.getJarName(), pipeline); - pidByName.forEach(pid -> killPid(pid, pipeline)); - } - - private List getPidByName(String appName, Pipeline pipeline) - { - List list = new ArrayList<>(); - ProcessBuilder processBuilder = AgentConfig.WINDOW ?// - new ProcessBuilder("cmd.exe", "/c", "wmic process where \"name='java.exe' and CommandLine like '%%" + appName + "%%'\" get ProcessId /value | findstr \"=\"")// - : new ProcessBuilder("sh", "-c", "ps aux | grep " + appName + " | grep -v grep | awk '{print $2}'"); - try - { - Process process = processBuilder.start(); - try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) - { - String line; - while ((line = input.readLine()) != null) - { - log.debug("命令输出:{}", line); - if (StringUtil.isNotBlank(line)) - { - String pid = WINDOW ? line.substring(10) : line; - if (!PID.equalsIgnoreCase(pid)) - { - list.add(pid); - } - } - } - } - process.destroy(); - String msg = list.isEmpty() ? STR.format("通过应用名称:{}检查,未能发现进程", appName) : STR.format("通过应用名称:{}查询,一共发现 PID:{}", appName, String.join(",", list)); - log.debug(msg); - pipeline.fireWrite(new LogReport().setContent(msg)); - return list; - } - catch (Throwable e) - { - log.error("通过应用名称:{}获取应用出现异常", appName, e); - pipeline.fireWrite(new LogReport().setContent(STR.format("通过应用名称:{}获取应用出现异常。异常信息:{}", appName, e))); - return list; - } - } - - public void killPid(String pid, Pipeline pipeline) - { - ProcessBuilder builder = WINDOW ? new ProcessBuilder("cmd.exe", "/C", "taskkill /F /PID " + pid) : new ProcessBuilder("kill", "-9", pid); - try - { - Process process = builder.start(); - process.waitFor(); - process.destroy(); - String msg = STR.format("终止进程:{}", pid); - log.debug(msg); - pipeline.fireWrite(new LogReport().setContent(msg)); - } - catch (Throwable e) - { - log.error("终止进程:{}出现异常", pid, e); - pipeline.fireWrite(new LogReport().setContent(STR.format("终止进程:{}出现异常。异常信息:{}", pid, e))); - } - } - - public void startJar(String relativePath, Pipeline pipeline) - { - File targetJarFile = new File(DIR_PATH, relativePath); - if (!targetJarFile.exists()) - { - pipeline.fireWrite(new LogReport().setContent(STR.format("文件:{}不存在,无法启动对应的 jar", targetJarFile.getAbsolutePath()))); - return; - } - String fileName = targetJarFile.getName(); - int index = fileName.lastIndexOf("."); - String fileNameWithoutExtension = fileName.substring(0, index); - String extension = fileName.substring(index); - File copyFile = new File(targetJarFile.getParentFile(), fileNameWithoutExtension + "_copy" + extension); - try - { - Files.copy(targetJarFile.toPath(), copyFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - } - catch (Throwable e) - { - pipeline.fireWrite(new LogReport().setContent(STR.format("复制文件:{}失败,异常信息:{}", copyFile.getAbsolutePath(), e))); - return; - } - pipeline.fireWrite(new LogReport().setContent(STR.format("复制文件:{}成功,现在准备启动", copyFile.getAbsolutePath()))); - ProcessBuilder builder = WINDOW ? new ProcessBuilder("java", "-jar", copyFile.getAbsolutePath()) : new ProcessBuilder("nohup", "java", "-jar", copyFile.getAbsolutePath(), "&"); - new Thread(() -> { - Process process = null; - try - { - process = builder.start(); - try (BufferedReader reader = process.inputReader(StandardCharsets.UTF_8)) - { - while (reader.readLine() != null) - { - ; - } - } - } - catch (IOException e) - { - throw new RuntimeException(e); - } - finally - { - if (process != null) - { - process.destroy(); - } - } - }).start(); + List pidByName = PlatformHelper.getPidByName(stopJar.getJarName(), pipeline); + pidByName.forEach(pid -> PlatformHelper.killPid(pid, pipeline)); } } diff --git a/src/main/java/org/tianhe/agent/control/DownloadFileHandler.java b/src/main/java/org/tianhe/agent/control/DownloadFileHandler.java index ea8d9c5..9085f51 100644 --- a/src/main/java/org/tianhe/agent/control/DownloadFileHandler.java +++ b/src/main/java/org/tianhe/agent/control/DownloadFileHandler.java @@ -7,8 +7,8 @@ import com.jfirer.jnet.common.api.ReadProcessor; import com.jfirer.jnet.common.api.ReadProcessorNode; import lombok.Data; import org.tianhe.agent.AgentConfig; +import org.tianhe.agent.PlatformHelper; import org.tianhe.common.command.Command; -import org.tianhe.common.command.impl.ReBootJar; import org.tianhe.common.packet.FileInfoResp; import org.tianhe.common.packet.FileSegmentReq; import org.tianhe.common.packet.FileSegmentResp; @@ -19,6 +19,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; +import java.util.List; import static org.tianhe.common.command.Command.UPDATE_JAR_VERSION_AND_REBOOT; @@ -123,8 +124,9 @@ public class DownloadFileHandler implements ReadProcessor pipeline.fireWrite(new LogReport().setContent(STR.format("文件:{}更新成功", fileDownload.getRelativePath()))); if (fileDownload.getCommand() == UPDATE_JAR_VERSION_AND_REBOOT) { - ReBootJar reBootJar = new ReBootJar().setJarNameWithoutExtension(fileDownload.getJarNameWithoutExtension()).setRelativePath(fileDownload.getRelativePath()); - next.fireRead(reBootJar); + List pidByName = PlatformHelper.getPidByName(fileDownload.getJarNameWithoutExtension(), pipeline); + pidByName.forEach(pid -> PlatformHelper.killPid(pid, pipeline)); + PlatformHelper.startJar(fileDownload.getRelativePath(), pipeline); } } } diff --git a/src/main/java/org/tianhe/common/command/Command.java b/src/main/java/org/tianhe/common/command/Command.java index 1bddd95..c027f5a 100644 --- a/src/main/java/org/tianhe/common/command/Command.java +++ b/src/main/java/org/tianhe/common/command/Command.java @@ -2,11 +2,11 @@ package org.tianhe.common.command; public interface Command { - int REBOOT_JAR = 1; - int STOP_JAR = 2; - int UPDATE_JAR_VERSION = 3; + int REBOOT_JAR = 1; + int STOP_JAR = 2; + int UPDATE_JAR_VERSION = 3; int UPDATE_JAR_VERSION_AND_REBOOT = 4; - + int UPDATE_ZIP_VERSION = 5; int commandType(); } diff --git a/src/main/java/org/tianhe/common/command/impl/UpdateZipVersion.java b/src/main/java/org/tianhe/common/command/impl/UpdateZipVersion.java new file mode 100644 index 0000000..477f9d6 --- /dev/null +++ b/src/main/java/org/tianhe/common/command/impl/UpdateZipVersion.java @@ -0,0 +1,21 @@ +package org.tianhe.common.command.impl; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.tianhe.common.command.Command; + +@Data +@Accessors(chain = true) +public class UpdateZipVersion implements Command +{ + private String relativePath; + private String appName; + private String jarNameWithoutExtension; + private String versionFileDate; + private String fileId; + @Override + public int commandType() + { + return UPDATE_ZIP_VERSION; + } +}