192.168.9.165 1 tydzień temu
rodzic
commit
50b0fdfded

+ 94 - 0
src/main/java/com/fdkankan/fusion/AppListener.java

@@ -0,0 +1,94 @@
+package com.fdkankan.fusion;
+
+
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.system.SystemUtil;
+import com.fdkankan.fusion.config.CacheUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.WebApplicationContext;
+
+import javax.annotation.Resource;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+@Component
+@Slf4j
+public class AppListener implements ApplicationRunner {
+
+    @Resource
+    private WebApplicationContext applicationContext;
+
+    @Override
+    public void run(ApplicationArguments args) {
+        if (CacheUtil.settingEntity.getPid()<= 0) {
+           log.info("未配置 app.monitorPid,跳过 PID 监听。");
+            return;
+        }
+
+        log.info("启动监听 PID: " + CacheUtil.settingEntity.getPid());
+
+        Thread monitorThread = new Thread(() -> {
+            while (true) {
+                try {
+                    if (!isProcessAlive(CacheUtil.settingEntity.getPid())) {
+                        System.out.println("目标 PID 不存在,准备退出 SpringBoot 服务...");
+                        shutdownApplication();
+                        break;
+                    }
+                    Thread.sleep(5000);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        monitorThread.setDaemon(true);
+        monitorThread.start();
+    }
+
+    /**
+     * 判断 PID 是否存活 (Java 8 版本,使用系统命令)
+     */
+    private boolean isProcessAlive(long pid) {
+        try {
+            if (SystemUtil.getOsInfo().isWindows()) {
+                // Windows 使用 tasklist
+                Process process = Runtime.getRuntime().exec("tasklist /FI \"PID eq " + pid + "\"");
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        if (line.contains(String.valueOf(pid))) {
+                            return true;
+                        }
+                    }
+                }
+            } else {
+                // Linux / Mac 使用 kill -0
+                Process process = Runtime.getRuntime().exec("kill -0 " + pid);
+                int exitCode = process.waitFor();
+                return exitCode == 0;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return false;
+    }
+
+    /**
+     * 优雅关闭 SpringBoot,并退出 JVM
+     */
+    private void shutdownApplication() {
+        try {
+            SpringApplication.exit(applicationContext, () -> 0);
+        } finally {
+            System.exit(0);
+        }
+    }
+}

+ 1 - 0
src/main/java/com/fdkankan/fusion/task/SettingEntity.java

@@ -13,4 +13,5 @@ public class SettingEntity {
     private Integer laserPort;
     private Integer meshPort;
     private Integer fusePort;
+    private Long pid;
 }