2017-07-03 59 views
-1

我目前有一個正在運行的'cron'服務器。它應該執行所有需要在將來運行的定時命令。 這是服務器所做的唯一的事情。使用setTimeout延遲多分鐘的Cron服務器()

工作原理:在我自己的筆記本電腦上運行這些功能,一切都按時完成。

什麼壞:在服務器上運行多天的功能。

我的代碼都放在一個明確的項目(節點),因此呼叫可以通過其他服務器進行添加更多的「crons」

文件夾佈局:

app.js 
-api/ 
--crons/ 
---router.js 
---functions.js 
--.../ 

在函數文件我的功能添加一個cron並執行它。

const _ = require('lodash'); 
const Crons = []; 
const moment = require('moment'); 

const functions = { 

addCron: (toExecute, dateTime, id, name) => { 
    console.log('Cron', dateTime, name, id); 
    const now = new Date().getTime(); 
    const then = new Date(dateTime).getTime(); 
    const diff = Math.max(then - now, 0); 

    let cronJob; 
    if (diff >= Math.pow(2, 31)) { 
     if(functions.get(name)) { 

     } 
     cronJob = setTimeout(() => { 
     functions.remove(name); 
     functions.addCron(toExecute, dateTime, id, name); 
     }, diff); 
     Crons.push({ 
     name: name, 
     job: cronJob 
     }); 
    } else { 
     if(functions.get(name)) { 
     functions.remove(name); 
     } 
     cronJob = setTimeout(() => { 
     console.log(`Started cron: ${name} at ${new Date()}`); 
     toExecute(id); 
     functions.remove(name); 
     }, diff); 
     Crons.push({ 
     name: name, 
     job: cronJob 
     }); 
    } 

    } 
}; 

module.exports = functions; 

目前我的日誌,當我運行這個地方告訴我,所有的功能被執行大約1毫秒太晚了(這是罰款)。 而現場服務器上的日誌告訴我,功能每天晚7分鐘運行。

日誌

1|cronserver | 2017-06-30 18:00:07.195000000: Cron 2017-07-01T17:00:00.000Z YQkWN6BmX8eqzQHC9startCheck YQkWN6BmX8eqzQHC9 
1|cronserver | 2017-06-30 18:00:07.195000000: Cron 2017-07-01T17:30:00.000Z 7c2yPyfjKDuujKQjhstartCheck 7c2yPyfjKDuujKQjh 
1|cronserver | 2017-06-30 18:00:07.196000000: Cron 2017-07-02T17:00:00.000Z PQKoboRpSkWeTufSdstartCheck PQKoboRpSkWeTufSd 
1|cronserver | 2017-06-30 18:00:07.196000000: Cron 2017-07-02T17:30:00.000Z yLFaAjACB9uNPd4YvstartCheck yLFaAjACB9uNPd4Yv 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-01T17:30:00.000Z YQkWN6BmX8eqzQHC9start YQkWN6BmX8eqzQHC9 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-01T18:00:00.000Z 7c2yPyfjKDuujKQjhstart 7c2yPyfjKDuujKQjh 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-02T17:30:00.000Z PQKoboRpSkWeTufSdstart PQKoboRpSkWeTufSd 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-02T18:00:00.000Z yLFaAjACB9uNPd4Yvstart yLFaAjACB9uNPd4Yv 
1|cronserver | 2017-07-01 17:07:32.253000000: Started cron: YQkWN6BmX8eqzQHC9startCheck at Sat Jul 01 2017 17:07:32 GMT+0000 (UTC) 
1|cronserver | 2017-07-01 17:37:33.160000000: Started cron: 7c2yPyfjKDuujKQjhstartCheck at Sat Jul 01 2017 17:37:33 GMT+0000 (UTC) 
1|cronserver | 2017-07-01 17:37:33.161000000: Started cron: YQkWN6BmX8eqzQHC9start at Sat Jul 01 2017 17:37:33 GMT+0000 (UTC) 
1|cronserver | 2017-07-01 18:07:34.070000000: Started cron: 7c2yPyfjKDuujKQjhstart at Sat Jul 01 2017 18:07:34 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 17:14:24.678000000: Started cron: PQKoboRpSkWeTufSdstartCheck at Sun Jul 02 2017 17:14:24 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 17:44:25.587000000: Started cron: yLFaAjACB9uNPd4YvstartCheck at Sun Jul 02 2017 17:44:25 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 17:44:25.588000000: Started cron: PQKoboRpSkWeTufSdstart at Sun Jul 02 2017 17:44:25 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 18:14:26.496000000: Started cron: yLFaAjACB9uNPd4Yvstart at Sun Jul 02 2017 18:14:26 GMT+0000 (UTC) 

該服務器確實正在運行這些功能的唯一的事情。任何幫助將不勝感激。

TL; DR我的setTimout函數運行較晚。我如何解決這個問題

+0

你使用node.js嗎? – pokeybit

+0

是的,我確實,現在將它添加爲標籤。 – mitchken

+0

'functions.remove'是什麼?你有沒有清理過「克朗斯」?你當前的代碼增加了它的限制:它會逐漸減慢一切... – dfogni

回答

1

setTimeout只能執行一次,所以我不認爲這是一個「cron作業」,而是一個你希望在未來某個時候執行一次的作業。除此之外,setTimeout並不意味着確切,並且有multiple known reasons why your setTimeout timer executes at the wrong timesetTimeout的工作原理是它在事件隊列中創建一個事件,直到隊列釋放後它纔會執行您的代碼as explained here。我可以很容易地看到如果有多個setTimeout函數在運行,它會在執行時造成延遲。或者更有可能你有其他內存泄漏問題,這只是在這裏冒泡。

無論有什麼其他的選擇來完成你想要做的事情。我已經使用node-cron進行實際的cron作業,它非常的甜美。在他們自己的隊列上運行單個作業也有多種方式,如KueRabbitMQ

+0

不是節點cron在它自己​​的函數中使用setTimeout嗎?那麼他們如何更精確? – mitchken

+0

這裏是非常類似的討論https://github.com/kelektiv/node-cron/issues/218和https://github.com/node-schedule/node-schedule/issues/368 - 他們討論了運行數千個setTimeout在一個最小延遲的時間。在執行的代碼中,最有可能運行阻塞事件循環的同步代碼。我建議讓你的cron作業和實際執行的代碼在不同的進程上運行。 – jjbskir