簡體   English   中英

如何檢測預定的SpringBoot任務是否已死鎖?

[英]How to detect if a Scheduled SpringBoot task has been deadlocked?

我有一個使用SpringBoot的計划任務,該任務計划在周一至周五上午10點運行。 我正在docker容器中運行我的應用程序,並且我的機器從晚上6點到晚上9點被掛起。 啟動計算機時,除非在計划的時間之前重新啟動容器,否則計划的10個小時的任務不會運行。 我有應用程序日志,發生這種情況時,在帶有@Scheduled批注的方法內部沒有日志記錄發生。 我相信這是一個僵局。 我想知道是否有任何方法可以通過編程方式檢測Springboot Scheduled中的死鎖。

我的Cron表情:“ 0 0 10 * * MON-FRI”

注意:我正在計算機上進行測試,以便以后在適當的服務器上托管。

AFAIK在Java中沒有標准的方法來檢測系統是否處於待機/休眠狀態。 Spring中的調度基於Java中的計時設施,這些設施不適合在OS睡眠或休眠條件下使用。 簡而言之,如果JVM無法檢測到系統何時進入待機狀態,那么Spring也無法。

在我看來,您有以下選擇:

  • 恢復系統后通知應用程序,然后重新安排任務。 這是在Ubuntu上圍繞pm utils構建的可能解決方案 是針對Windows的。
  • 添加一個額外的任務,該任務每10秒運行一次,並讀取系統時間。 如果兩個時間讀數之間存在明顯差異,則意味着您的系統進入了睡眠狀態,然后又恢復了。

例如,以下示例在檢測到大於1s的時間間隔( delta )時重新啟動上下文:

@SpringBootApplication
@EnableScheduling
public class Application {

  private static ConfigurableApplicationContext context;

  public static void main(String[] args) {
    context = SpringApplication.run(Application.class, args);
  }

  static LocalTime lastDetectedTime;
  static long delta = 1000;
  static final long CHECK_INTERVAL = 5000;

  @Scheduled(fixedDelay = CHECK_INTERVAL, initialDelay = CHECK_INTERVAL)
  public static void restartIfTimeMismatch() {

    if(lastDetectedTime == null) {
      lastDetectedTime = LocalTime.now();
    }
    LocalTime currentTime = LocalTime.now();
    long diff = Duration.between(lastDetectedTime, currentTime).toMillis();
    lastDetectedTime = currentTime;

    if(diff > CHECK_INTERVAL + delta) {
      Thread thread = new Thread(() -> {
        context.close();
        context = SpringApplication.run(Application.class);
      });

      lastDetectedTime = null;
      thread.setDaemon(false);
      thread.start();

    }
  }
}

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM