|
|
@@ -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 版本,使用系统命令)
|
|
|
*/
|