经过数周的迭代,nodejs setTimout循环停止了

时间:2018-08-13 15:55:12

标签: node.js express settimeout

已解决:这是一个节点错误。在〜25天(2 ^ 32毫秒)后发生,请参阅答案以了解详细信息。

此循环中是否有最大迭代次数?

function do_every_x_seconds() {
    //Do some basic things to get x
    setTimeout( do_every_x_seconds, 1000 * x );                                                                
};  

据我了解,这被认为是使事物定期运行的“最佳实践”方式,因此,我对此非常怀疑。

我正在Ubuntu上运行具有大量超时循环的Express服务器。 一个循环每秒运行一次,基本上打印出时间戳。 每5秒调用一次外部http请求的请求 并且每X X 30到300秒运行一次。

看起来一切正常。但是,在25天没有任何使用且经过数百万次迭代之后,该节点实例仍处于运行状态,但是所有三个setTimout循环均已停止。根本没有错误消息的报告。

甚至更奇怪的是Express服务器仍在运行,我可以将http网站加载到与打印定期时间戳记的控制台相同的控制台上。

我不确定它是否相关,但是我也使用--expose-gc标志运行nodejs并执行定期垃圾回收并监视内存是否在可接受的范围内。

这是一台开发服务器,因此我保留了该实例,以防万一我可以采取什么措施进一步解决该问题。

事件循环可能会以某种方式丢弃所有计时器吗?

2 个答案:

答案 0 :(得分:3)

我有a similar problem with setInterval()

我认为这可能是由于Node.js中的以下错误引起的,该错误最近已修复:setInterval callback function unexpected halt #22149

更新:似乎该修复程序已在Node.js 10.9.0中发布。

答案 1 :(得分:2)

我认为问题在于您依赖setTimeout内保持活跃。 setTimeout非常适合定期运行功能,但我认为您不应在较长时间内信任它。考虑以下问题:can setInterval drift over time?及其关联问题之一:setInterval interval includes duration of callback #7346

如果您需要在特定时间断断续续地进行操作,则更好的解决方法是安排cron个执行任务的任务。它们更具弹性,并且故障是在系统级别的日志中记录的,而不是在节点流程中记录的。

Node.js setTimeout for 24 hours - any caveats?是一个很好的相关答案/问题,其中提到使用npm软件包cron进行任务调度。