|
@@ -0,0 +1,98 @@
|
|
|
+package com.fdkankan.scene.schedule;
|
|
|
+
|
|
|
+
|
|
|
+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.scene.config.FdkkLaserConfig;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.boot.SpringApplication;
|
|
|
+import org.springframework.context.ConfigurableApplicationContext;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class AppListener {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ FdkkLaserConfig fdkkLaserConfig;
|
|
|
+
|
|
|
+ private final ConfigurableApplicationContext context;
|
|
|
+
|
|
|
+ public AppListener(ConfigurableApplicationContext context) {
|
|
|
+ this.context = context;
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ if (fdkkLaserConfig.getPid() <= 0) {
|
|
|
+ log.info("未配置 app.monitorPid,跳过 PID 监听。");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("启动监听 PID: " + fdkkLaserConfig.getPid());
|
|
|
+
|
|
|
+ Thread monitorThread = new Thread(() -> {
|
|
|
+ while (true) {
|
|
|
+ try {
|
|
|
+ if (!isProcessAlive(fdkkLaserConfig.getPid())) {
|
|
|
+ System.out.println("目标 PID 不存在,准备退出 SpringBoot 服务...");
|
|
|
+ shutdownApplication();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Thread.sleep(2000);
|
|
|
+ } 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(context, () -> 0);
|
|
|
+ } finally {
|
|
|
+ System.exit(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|