2017-07-03 55 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