使用NodeJS安排重复的HTTP请求

时间:2018-12-17 14:53:07

标签: node.js cron scheduled-tasks

在我的Node应用程序中,我需要安排每周一次的API请求以从第三方网站获取一些数据。我有成千上万的用户,他们的帐户中设置了多个时间表。

我能够使用node-cron编写重复的计划功能。但是随着应用程序规模的扩大和用户数量的增加,我认为Cronjobs并不是解决此问题的更好方法。

还有其他选择可以实现我的最终目标吗?

1 个答案:

答案 0 :(得分:0)

这是一个开放性问题,但让我提出一些潜在的设计方法。

假设您有许多用户,每个用户有许多时间表,并且每个时间表都有时间规范(定时格式或其他格式):上一次运行时间表时,将其与每个时间表一起存储。创建一个“作业”(任务,程序等),该“作业”在运行时将遍历所有用户并评估其时间表:对于每个时间表,请使用上次运行时间及其时间规范来计算下一个时间表运行时间,如果当前时间是该时间或该时间之后,则将时间表添加到列表中。然后循环遍历该列表,运行每个Schedule(需要执行的所有任务),并更新上次运行时间。

通过这种方式构造工作,您可以选择是否使用cron。您可以每天手动运行一次该程序,可以将其安排为在主应用程序服务器上每60秒运行一次(大概对于许多运行情况,它将退出而无需执行任何操作,因为没有更多的用户需要运行计划了)。我认为系统cron对于安排此类任务仍然有用,但这取决于您。

从规模上讲(假设您最终有100,000个用户,每个用户具有1-5个计划),我建议使用基于作业的排队系统。使用node-resque之类的东西,您可以使用cron每5分钟启动一次时间表检查作业,这将为每个所需的时间表添加单独的运行时间表作业跑步。最终,您将有太多用户无法在单个计划检查器中进行评估。可以修改计划检查器作业以仅计算您的用户,对其进行分片并启动较小的计划检查器作业(一个用于用户1-5000,一个用于用户5001- 10000等)。这样一来,您就可以向外扩展并利用5或10或15个Resque工作者。

(我建议重做,因为我是Redis的粉丝,但是您可以轻松地使用其他排队系统,甚至,如果您在生产中使用Jenkins,那么一系列的Jenkins作业也会相互影响并使用Jenkins工人机器来运行工作。这是通过这种方式构造跑步者的优势,您可以将其映射到几乎任何技术上。)

您仍然要解决很多难题:如果所有这些调用都针对一个远程API,则必须检测并处理远程API的过载并获得速率限制错误(这可能会影响您的访问量决定横向扩展,如果每秒将1000个请求限制为5个请求,那么对远程服务器的支持是没有意义的。您还需要考虑如果发生故障并且几个小时不运行作业会发生什么情况(取决于您的应用程序,您是否希望用户的计划“赶上”并比计划的每次运行晚运行) ,还是应该“跳到”最新时间,而忽略所浪费的时间)。其他细微差别包括时间表在运行队列中被用户删除或更改,等等。

祝你好运!