树列表
This commit is contained in:
		| @ -1,9 +1,12 @@ | ||||
| package com.yj.earth.common.config; | ||||
|  | ||||
| import com.yj.earth.common.util.SdkUtil; | ||||
| import lombok.Data; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import javax.annotation.PostConstruct; | ||||
|  | ||||
| @Data | ||||
| @Component | ||||
| public class ServerConfig { | ||||
| @ -13,6 +16,10 @@ public class ServerConfig { | ||||
|     @Value("${server.host}") | ||||
|     private String host; | ||||
|  | ||||
|     @Value("${sdk.port}") | ||||
|     private int sdkPort; | ||||
|  | ||||
|     @PostConstruct | ||||
|     public void initSdkPort() { | ||||
|         this.sdkPort = SdkUtil.getServerPortFromSdkConfig(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,10 +2,10 @@ package com.yj.earth.common.util; | ||||
|  | ||||
| import com.yj.earth.common.constant.GlobalConstant; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.core.io.ClassPathResource; | ||||
| import org.yaml.snakeyaml.Yaml; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| @ -18,24 +18,22 @@ import java.util.stream.Collectors; | ||||
| public class SdkUtil { | ||||
|     // 保存SDK进程引用 | ||||
|     private static Process sdkProcess; | ||||
|     // 保存SDK端口号、用于关闭时强制终止 | ||||
|     private static Integer sdkPort; | ||||
|  | ||||
|     // 对外提供的启动入口 | ||||
|     public static void startSdkIfConfigured() throws IOException { | ||||
|         // 读取配置 | ||||
|         sdkPort = getSdkPortFromYamlConfig(); | ||||
|         // 读取SDK端口 | ||||
|         Integer serverPort = getServerPortFromSdkConfig(); | ||||
|         // 未配置则不启动 | ||||
|         if (sdkPort == null) { | ||||
|             log.info("请先配置SDK端口"); | ||||
|         if (serverPort == null) { | ||||
|             log.info("未配置SDK端口"); | ||||
|             return; | ||||
|         } | ||||
|         // 配置存在时、正常启动SDK | ||||
|         startSdkJar(sdkPort); | ||||
|         startSdkJar(serverPort); | ||||
|     } | ||||
|  | ||||
|     // 接收已确认的端口、启动SDK | ||||
|     private static void startSdkJar(int sdkPort) throws IOException { | ||||
|     private static void startSdkJar(int serverPort) throws IOException { | ||||
|         // 获取项目根目录(当前工作目录) | ||||
|         String projectRoot = System.getProperty("user.dir"); | ||||
|         // 获取SDK完整路径 | ||||
| @ -44,20 +42,41 @@ public class SdkUtil { | ||||
|         File sdkJarFile = new File(sdkJarPath); | ||||
|         if (!sdkJarFile.exists() || !sdkJarFile.isFile()) { | ||||
|             log.error("SDK不存在或不是有效文件:{}", sdkJarPath); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 获取SDK所在目录(sdk目录) | ||||
|         File sdkDir = sdkJarFile.getParentFile(); | ||||
|         if (sdkDir == null || !sdkDir.exists()) { | ||||
|             log.error("无法获取SDK所在目录:{}", sdkJarPath); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 构建JDK的java可执行文件路径(适配新目录结构) | ||||
|         String javaExecutablePath = getJavaExecutablePath(sdkDir); | ||||
|         File javaExecutable = new File(javaExecutablePath); | ||||
|         if (!javaExecutable.exists() || !javaExecutable.canExecute()) { | ||||
|             log.error("JDK可执行文件不存在或不可执行:{}", javaExecutablePath); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         log.info("准备启动SDK: {}", sdkJarPath); | ||||
|         log.info("使用SDK端口: {}", sdkPort); | ||||
|         log.info("使用JDK路径: {}", javaExecutablePath); | ||||
|         log.info("使用SDK端口: {}", serverPort); | ||||
|  | ||||
|         // 构建启动命令、添加 -Dserver.port 参数 | ||||
|         List<String> command = new ArrayList<>(); | ||||
|         command.add("java"); | ||||
|         command.add("-Dserver.port=" + sdkPort); | ||||
|         command.add(javaExecutablePath);  // 使用指定路径的java | ||||
|         command.add("-Dserver.port=" + serverPort); | ||||
|         command.add("-jar"); | ||||
|         command.add(sdkJarPath); | ||||
|  | ||||
|         // 构建进程启动器 | ||||
|         ProcessBuilder processBuilder = new ProcessBuilder(command); | ||||
|         // 打印执行的命令 | ||||
|         String commandStr = command.stream().collect(Collectors.joining(" ")); | ||||
|         log.info("执行命令: {}", commandStr); | ||||
|  | ||||
|         // 输出SDK的控制台日志到当前应用的日志中 | ||||
|         processBuilder.redirectErrorStream(true); | ||||
|         // 日志文件路径建议优化: 避免与项目根目录混淆 | ||||
| @ -67,9 +86,11 @@ public class SdkUtil { | ||||
|             sdkLogFile.getParentFile().mkdirs(); | ||||
|         } | ||||
|         processBuilder.redirectOutput(sdkLogFile); | ||||
|  | ||||
|         // 启动进程(非阻塞) | ||||
|         sdkProcess = processBuilder.start(); | ||||
|         log.info("SDK已在后台启动、进程ID: {}", sdkProcess.pid()); | ||||
|  | ||||
|         // 注册JVM关闭钩子、在主程序退出时关闭SDK进程 | ||||
|         Runtime.getRuntime().addShutdownHook(new Thread(() -> { | ||||
|             if (sdkProcess != null && sdkProcess.isAlive()) { | ||||
| @ -82,13 +103,13 @@ public class SdkUtil { | ||||
|                     if (terminated) { | ||||
|                         log.info("SDK进程已成功停止"); | ||||
|                     } else { | ||||
|                         log.warn("SDK进程未能正常停止、尝试通过端口{}强制终止...", sdkPort); | ||||
|                         log.warn("SDK进程未能正常停止、尝试通过端口{}强制终止...", serverPort); | ||||
|                         // 通过端口强制终止 | ||||
|                         boolean killSuccess = PortKillUtil.killProcessByPort(sdkPort); | ||||
|                         boolean killSuccess = PortKillUtil.killProcessByPort(serverPort); | ||||
|                         if (killSuccess) { | ||||
|                             log.info("已通过端口{}强制终止SDK进程", sdkPort); | ||||
|                             log.info("已通过端口{}强制终止SDK进程", serverPort); | ||||
|                         } else { | ||||
|                             log.error("通过端口{}强制终止SDK进程失败", sdkPort); | ||||
|                             log.error("通过端口{}强制终止SDK进程失败", serverPort); | ||||
|                         } | ||||
|                     } | ||||
|                 } catch (InterruptedException e) { | ||||
| @ -100,26 +121,61 @@ public class SdkUtil { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 从配置文件读取SDK端口配置 | ||||
|      * 根据新目录结构获取JDK的java可执行文件路径 | ||||
|      */ | ||||
|     private static Integer getSdkPortFromYamlConfig() { | ||||
|     private static String getJavaExecutablePath(File sdkDir) { | ||||
|         // 从sdk目录向上两级找到根目录(sdk -> app -> 根目录) | ||||
|         File appDir = sdkDir.getParentFile(); | ||||
|         if (appDir == null || !appDir.exists()) { | ||||
|             log.error("无法获取app目录(sdk的父目录)"); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         File rootDir = appDir.getParentFile(); | ||||
|         if (rootDir == null || !rootDir.exists()) { | ||||
|             log.error("无法获取根目录(app的父目录)"); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         // 判断操作系统类型 | ||||
|         boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win"); | ||||
|         // 构建JDK路径:根目录/jdk/bin/java(或java.exe) | ||||
|         String javaRelativePath = "jdk" + File.separator + "bin" + File.separator + | ||||
|                 (isWindows ? "java.exe" : "java"); | ||||
|         return new File(rootDir, javaRelativePath).getAbsolutePath(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 从sdk文件夹下的application.yml读取server.port配置 | ||||
|      */ | ||||
|     public static Integer getServerPortFromSdkConfig() { | ||||
|         Yaml yaml = new Yaml(); | ||||
|         try (InputStream inputStream = new ClassPathResource("application.yml").getInputStream()) { | ||||
|         String projectRoot = System.getProperty("user.dir"); | ||||
|         File sdkConfigFile = new File(projectRoot, "sdk/application.yml"); | ||||
|  | ||||
|         if (!sdkConfigFile.exists() || !sdkConfigFile.isFile()) { | ||||
|             log.error("配置文件不存在: {}", sdkConfigFile.getAbsolutePath()); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         try (InputStream inputStream = new FileInputStream(sdkConfigFile)) { | ||||
|             // 解析YAML文件为Map | ||||
|             Map<String, Object> yamlMap = yaml.load(inputStream); | ||||
|             // 逐级获取配置 | ||||
|             if (yamlMap.containsKey("sdk")) { | ||||
|                 Object sdkObj = yamlMap.get("sdk"); | ||||
|                 if (sdkObj instanceof Map) { | ||||
|                     Map<?, ?> sdkMap = (Map<?, ?>) sdkObj; | ||||
|                     if (sdkMap.containsKey("port")) { | ||||
|                         return ((Number) sdkMap.get("port")).intValue(); | ||||
|             // 逐级获取server.port配置 | ||||
|             if (yamlMap.containsKey("server")) { | ||||
|                 Object serverObj = yamlMap.get("server"); | ||||
|                 if (serverObj instanceof Map) { | ||||
|                     Map<?, ?> serverMap = (Map<?, ?>) serverObj; | ||||
|                     if (serverMap.containsKey("port")) { | ||||
|                         return ((Number) serverMap.get("port")).intValue(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             log.error("未配置SDK端口"); | ||||
|             log.error("sdk配置文件中未配置server.port"); | ||||
|         } catch (IOException e) { | ||||
|             log.error("读取配置文件失败", e); | ||||
|             log.error("读取sdk配置文件失败", e); | ||||
|         } catch (ClassCastException e) { | ||||
|             log.error("sdk配置文件中server.port格式错误,应为数字类型", e); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 ZZX9599
					ZZX9599