|
@@ -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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|