gpt4 book ai didi

docker - 防止在 docker 上的 nest.js 中运行多个 cron

转载 作者:行者123 更新时间:2023-12-05 08:24:53 25 4
gpt4 key购买 nike

在 docker 中,我们为我们的微服务使用了 deploy: replicas: 3。我们有一些 Cronjob,问题是运行所有 cronjob 的系统被调用了 3 次,这不是我们想要的。我们只想运行一次。 nest.js 中的 cron 示例:

  @Cron(CronExpression.EVERY_5_MINUTES)
async runBiEventProcessor() {
const calculationDate = new Date()
Logger.log(`Bi Event Processor started at ${calculationDate}`)

如何在不将副本更改为 1 的情况下仅运行此 cron 一次?

最佳答案

当 cron 或后台作业是同时运行多个实例的应用程序的一部分时,这是一个非常普遍的问题。

有多种方法可以处理这种情况。如果您没有具体的解决方案,以下是一些解决方法:

  1. 仅为后台处理创建一个单独的服务,并确保一次只有一个实例在运行。

  2. 将 cron 作业公开为 API 并触发 API 以启动后台处理。在这种场景下,负载均衡器只会将请求交给一个实例。这种方法将确保只有一个实例可以处理该作业。您仍然需要一个外部实体来访问 API,它可以是内部的或第三方的。

  3. 使用 Bull Queue 或提供类似功能的任何其他工具或库中的可重复作业功能。Bull 会将工作移交给任何活跃的处理器。这样,它可以确保作业仅由一个事件处理器处理一次。Nest.js 有 wrapper对于相同的。阅读有关 Bull 队列可重复作业的更多信息 here .

  4. 实现自定义锁定机制听起来并不难。其他框架中的许多其他调度程序都采用类似的原则来处理并发。

    • 如果您使用 RDBMS,请使用事务和锁定。在数据库中创建 cron 记录。第一个 cron 进入并处理后立即获取锁。其他并发作业将失败或超时,因为它们将无法获取锁。但是您需要在这种方法中处理一些情况,以使其无错误且完美无缺。
    • 如果您使用的是 MongoDB 或任何支持 TTL(生存时间)设置和唯一索引的类似数据库。将文档插入数据库,其中文档中的一个字段具有唯一约束,以确保另一作业无法再插入一个文档,因为它会因数据库级唯一约束而失败。另外,确保文档上有 TTL(Time-to-live index);这样,文档将在配置的时间后被删除。

如果您没有任何其他具体选项,这些是解决方法。

关于docker - 防止在 docker 上的 nest.js 中运行多个 cron,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70168350/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com