192.168.9.165 1 неделя назад
Родитель
Сommit
07be2a73f9
1 измененных файлов с 70 добавлено и 5 удалено
  1. 70 5
      src/main/java/com/fdkankan/fusion/AppListener.java

+ 70 - 5
src/main/java/com/fdkankan/fusion/AppListener.java

@@ -1,5 +1,6 @@
 package com.fdkankan.fusion;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.system.SystemUtil;
 import com.fdkankan.fusion.config.CacheUtil;
 import com.fdkankan.redis.util.RedisUtil;
@@ -13,7 +14,13 @@ import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.InputStreamReader;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.concurrent.TimeUnit;
 
 @Component
 @Slf4j
@@ -56,12 +63,12 @@ public class AppListener implements ApplicationRunner {
                     shutdownApplication();
                     break;
                 }
-
                 // 检测 PID
-                if (!isProcessAlive(pid)) {
-                    log.info("目标 PID 不存在,准备退出 SpringBoot 服务... pid={}", pid);
-                    shutdownApplication();
-                    break;
+                if (!checkPidExist(pid, 3, 200L)) {
+                    if (!isAppAlive(  CacheUtil.settingEntity.getBinPath() + File.separator +".statusrc")) {
+                        shutdownApplication();
+                        break;
+                    }
                 }
 
             } catch (Exception e) {
@@ -78,7 +85,65 @@ public class AppListener implements ApplicationRunner {
             }
         }
     }
+    /**
+     * 多次重试检查 PID 是否存活
+     *
+     * @param pid            进程 PID
+     * @param maxCheckTimes  最大检查次数
+     * @param waitTimeMillis 每次检查间的等待时间(毫秒)
+     */
+    private boolean checkPidExist(long pid, int maxCheckTimes, long waitTimeMillis) throws InterruptedException {
+        if (pid <= 0) {
+            return false;
+        }
+
+        for (int i = 1; i <= maxCheckTimes; i++) {
+            if (isProcessAlive(pid)) {
+                return true;
+            }
+            if (i < maxCheckTimes) {
+                Thread.sleep(waitTimeMillis);
+            }
+        }
+        return false;
+    }
+    /**
+     * 判断应用是否存活(10秒心跳)
+     *
+     * @param filePath 心跳文件路径
+     * @return 存活返回 true,超时或异常返回 false
+     */
+    public static boolean isAppAlive(String filePath) {
+        File file = new File(filePath);
 
+        // 文件不存在,直接认为应用不存活
+        if (!file.exists()) {
+            return false;
+        }
+
+        long lastModified = file.lastModified();
+        long currentTime = System.currentTimeMillis();
+        long timeout = TimeUnit.SECONDS.toMillis(3);
+        boolean flag=(currentTime - lastModified) <= timeout;
+        if (!flag){
+            LocalDateTime lastTime = LocalDateTime.ofInstant(
+                    Instant.ofEpochMilli(lastModified),
+                    ZoneId.systemDefault()
+            );
+
+            String formattedTime = lastTime.format(
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
+            );
+
+            log.error(
+                    "心跳文件已超过 3 秒未更新,准备退出 SpringBoot 服务,文件路径:{},最后更新时间:{}",
+                    filePath,
+                    formattedTime
+            );
+        }
+        // 超过 10 秒未更新
+        return flag;
+    }
     /**
      * 判断 PID 是否存活 (Java 8 版本,使用系统命令)
      */