簡體   English   中英

Spring的@Scheduled cron作業在預定時間之前觸發了幾毫秒

[英]Spring's @Scheduled cron job is triggering a few milliseconds before the scheduled time

我已經設置了Spring的@Scheduled ,每小時都有一個cron表達式,如下所示: trend.olap.local.loading.cron.expression0 0 * * * ?

@Scheduled(cron = "${trend.olap.local.loading.cron.expression}")
public void loadHoulyDataToLocalOlap() {
    try {
        // To calculate prev hour;
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR, -1);
        Date date = cal.getTime();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Loading hourly data into local olap :" + date
                    + ", and hour :" + hour);
        }

        dataIntegrationProcessor.loadHourlyDataToLocalOlap(hour);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Loading hourly data into local olap :" + date
                    + ", and hour :" + hour + " Completed.");
        }
    } catch (Exception e) {
        LOGGER.error("Error occured at loadHoulyDataToLocalOlap", e);
    }
}

這里我的目的是從當前日期和時間獲取小時值並將其傳遞給執行程序方法。

基本上我采取當前小時減1,所以在17:00,小時值應該是16。

但是如果你看到日志,則小時值為15.這是因為調度程序運行在16:59:59,831左右。 請參閱下面的log4j日志。 看起來cron作業在幾毫秒內完成並在17:00:00,000之前的幾毫秒內被觸發。

因此,我得到了錯誤的價值觀,而我的商業案例也失敗了。

如何讓cron在每小時的零毫秒內完全運行,而不是在幾毫秒之前?

DEBUG 2013-09-29 16:59:59,831 (TrendScheduler.java loadHoulyDataToLocalOlap:57) - Loading hourly data into local olap :Sun Sep 29 15:59:59 IST 2013, and hour :15
DEBUG 2013-09-29 16:59:59,831 (DataIntegrationProcessor.java loadHourlyDataToLocalOlap:57) - Loading hourly data for hour :15
INFO 2013-09-29 17:00:00,054 (KettleJobExecutor.java executeJob:73) - Job (24hr_populate_hour_data_job.kjb) executed successfully
DEBUG 2013-09-29 17:00:00,054 (TrendScheduler.java loadHoulyDataToLocalOlap:64) - Loading hourly data into local olap :Sun Sep 29 15:59:59 IST 2013, and hour :15 Completed.

簡短的回答是你不能使用cron選項。 cron表達式的分辨率是第二個,因此它將舍入到最接近的秒。 您可能能夠保證它至少在特定時間之后發生,但與cron完全不同。

您最好的選擇是實現自己的Trigger Trigger接口有一個方法,它返回java.util.Date以供下次執行(以毫秒為單位)。 從那里你可以注冊任務和觸發器,如下面的文檔所示: http//docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableScheduling.html

如果您打算插入正確的小時值,我認為更好的解決方案是根據可預測性較低的cron計划計算小時數。 只要它落在一秒鍾之內,您就可以簡單地獲取當前時間並將其轉換為最接近的小時,然后從那里獲取小時值。 您還可以添加警告/警報,通過收聽遲到超過一分鍾或遲到10分鍾等的任務,讓您知道cron是否表現不穩定。

雖然你可以改為調整cron時間表,但我認為這比在代碼中處理它更多,因為你在這一點上近似了近似值。 您可以在代碼中擁有更多控制權來處理超過100毫秒的簡單偏移

假設沒有任何其他時序問題,例如系統突然加載,Cron將忽略毫秒並暗示只能精確到一秒鍾內。

您有兩個選擇:1。在小時后幾秒鍾啟動cron作業2.更改小時計算以允許提前觸發作業。

在這兩個中,第一個是最簡單的,我不會把它稱為比使用浮點數時允許舍入問題更黑客。

暫無
暫無

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

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