我的情况...
我有一组 workers 计划定期运行,每个以不同的时间间隔运行,我想找到一个好的实现来管理它们的执行。
示例:假设我有一个 worker 每周去商店给我买一次牛奶。我想将此作业及其配置存储在 mysql 表中。但是,轮询表(每秒?)并查看哪些作业已准备好放入执行管道似乎是一个真的坏主意。
我所有的工作人员都是用 javascript 编写的,所以我使用 node.js 执行和 beanstalkd作为管道。
如果异步创建新作业(即安排工作人员在给定时间运行)并且我需要持久存储作业结果和配置,我该如何避免轮询表?
谢谢!
最佳答案
我同意这看起来不雅,但考虑到计算机的工作方式某事*某处*将不得不进行某种轮询才能弄清楚什么时候执行哪些作业。那么,让我们回顾一下您的一些选择:
轮询数据库表。这根本不是一个坏主意 - 如果您无论如何都将作业存储在 MySQL 中,这可能是最简单的选择。每秒一个查询的速率不算什么——试一试,您会发现您的系统甚至感觉不到它。
一些想法可以帮助您将其扩展到每秒数百个查询,或者只是降低系统资源需求:
- 创建第二个表“job_pending”,其中放置需要在接下来的 X 秒/分钟/小时内执行的作业。
- 每隔较长一段时间只对包含所有作业的大表运行一次查询,然后每隔较短一段时间填充您查询的小表。
- 从小表中删除已执行的作业以使其保持较小。
- 在您的“execute_time”(或您所称的任何名称)列上使用索引。
如果您必须进一步扩展,请将主作业表保留在数据库中,并使用我建议的第二个较小的表,只需将该表放在 RAM 中:作为数据库引擎中的内存表,或者在你的程序中的某种队列中。如果您也以极短的间隔查询队列 - 一些极端的用例会导致此处出现任何性能问题。
此选项的主要问题是您必须跟踪内存中但未执行的作业,例如由于系统崩溃 - 为您编写更多代码...
为一堆作业中的每一个创建一个线程(比如,所有需要在下一分钟执行的作业),然后调用 thread.sleep(millis_until_execution_time)(或者其他什么,我不太熟悉node.js)。
这个选项和no有同样的问题。 2 - 您必须在其中跟踪作业执行以进行崩溃恢复。这也是最浪费的 imo - 每个休眠作业线程仍然占用系统资源。
当然可能还有其他选项-我希望其他人有更多想法来回答。
只需意识到每秒轮询一次数据库并不是一个坏主意。在我看来,这是最直接的方式(记住 KISS),按照这种速度,您应该不会遇到性能问题,因此请避免过早优化。
关于javascript - 数据库支持的工作队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5603017/