简体   繁体   English

什么时候使用 setTimeout 和 Cron 比较合适?

[英]When is it appropriate to use a setTimeout vs a Cron?

I am building a Meteor application that is using a mongo database.我正在构建一个使用 mongo 数据库的 Meteor 应用程序。

I have a collection that could potentially have 1000s of documents that need to be updated at different times.我有一个可能有 1000 个需要在不同时间更新的文档的集合。

Do I run setTimeouts on creation or a cron job that runs every second and loops over every document?我是在创建时运行 setTimeouts 还是每秒运行一次并循环遍历每个文档的 cron 作业?

What are the pros and cons of doing each?每种做法的优缺点是什么?

To put this into context:把它放在上下文中:

I am building an online tournament system.我正在构建一个在线锦标赛系统。 I can have 100s of tournaments running which means I could have 1000s of matches.我可以进行 100 场比赛,这意味着我可以进行 1000 场比赛。

Each match needs to absolutely end at a specific time, and can end earlier under a condition.每场比赛都需要在特定时间绝对结束,并且可以在某个条件下提前结束。

Using an OS-level cron job won't work because you can only check with a 60-second resolution.使用操作系统级别的 cron 作业将不起作用,因为您只能使用 60 秒的分辨率进行检查。 So by "cron job", I think you mean a single setTimeout (or synced-cron ).因此,通过“cron job”,我认为您的意思是单个setTimeout (或synced-cron )。 Here are some thoughts:以下是一些想法:

Single setTimeout单组超时

strategy : Every second wake up and check a large number of matches, updating those which are complete.策略:每秒唤醒并检查大量匹配项,更新那些已完成的匹配项。 If you have multiple servers, you can prevent all but one of them from doing the check via synced-cron.如果您有多个服务器,则可以通过 synced-cron 阻止除其中之一之外的所有服务器进行检查。

The advantage of this strategy is that it's straightforward to implement.这种策略的优点是实施起来很简单。 The disadvantages are:缺点是:

  1. You may end up doing a lot of unnecessary database reads.您最终可能会进行大量不必要的数据库读取。
  2. You have to be extremely careful that your processing time does not exceed the length of the period between checks (one second).您必须非常小心,确保您的处理时间不超过检查之间的时间间隔(一秒)。

I'd recommend this strategy if you are confident that the runtime can be controlled.如果您确信可以控制运行时,我会推荐此策略。 For example, if you can index your matches on an endTime so only a few matches need to be checked in each cycle.例如,如果您可以在endTime索引您的匹配项,那么在每个周期中只需要检查几个匹配项。

Multiple setTimeouts多个 setTimeouts

strategy : Add a setTimeout for each match on creation or when the sever starts.策略:在创建时或服务器启动时为每个匹配添加一个setTimeout As each timeout expires, update the corresponding match.当每个超时到期时,更新相应的匹配项。

The advantage of this strategy is that it potentially removes a considerable amount of unnecessary database traffic.这种策略的优点是它可能会删除大量不必要的数据库流量。 The disadvantages are:缺点是:

  1. It may be a little more tricky to implement.实现起来可能有点棘手。 Eg you have to consider what happens on a server restart.例如,您必须考虑服务器重启时会发生什么。
  2. The naive implementation doesn't scale past a single server (see 1).天真的实现不会扩展到单个服务器(参见 1)。

I'd recommend this strategy if you think you will use a single server for the foreseeable future.如果您认为在可预见的未来将使用单个服务器,我会推荐此策略。


Those are the trade-offs which occurred to me given the choices you presented.鉴于您提出的选择,这些是我想到的权衡。 A more robust solution would probably involve technology outside of the meteor/mongo stack.更强大的解决方案可能会涉及到流星/mongo 堆栈之外的技术。 For example, storing match times in redis and then listening for keyspace notifications .例如,将匹配时间存储在 redis 中,然后侦听keyspace 通知

This is all a matter of preference, to be honest with you.老实说,这完全是个人喜好问题。

I'm a big fan of writing small, independent programs, that each do one thing, and do it well.我非常喜欢编写小的、独立的程序,每个程序都做一件事,而且做得很好。 If you're also like this, it's probably better to write separate programs to run periodically via cron.如果您也是这样,最好编写单独的程序以通过 cron 定期运行。

This way you get guaranteed OS-controlled precision for the time, and small, simple programs that are easy to debug outside the context of your webapp.通过这种方式,您可以保证操作系统控制的时间精度,以及易于在 web 应用程序上下文之外调试的小而简单的程序。

This is just a preference though.不过,这只是一种偏好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM