Spring Boot 调度程序为每个 Pod 运行 cron 作业

Dar*_*ren 15 cron kubernetes kubernetes-pod kubernetes-cluster

当前设置

我们的 kubernetes 集群设置有 3 个运行 spring boot 应用程序的 kubernetes pod。我们使用 Spring Boot Scheduler 每 12 小时运行一次作业来获取一些数据并缓存它。(有队列设置,但我不会继续这些细节,因为我的查询是在我们进入队列之前进行设置)

问题

因为我们有 3 个 pod,并且调度程序处于应用程序级别,所以我们对数据集进行 3 次调用,每个 pod 都会收到响应,并且在缓存中处理的 pod 首先成为主节点,其他 2 个 pod 会从该实例复制数据。

我认为这是一个问题,因为我们将增加作业数量以获得更多数据集,因此这将增加调用的数量。

我不是来自 DevOps 方面,并且天蓝色知识有限,因此我需要社区的一些帮助

需要

有哪些选项可以改善这一点?我想将 Cron 计划分开,只运行一次,而不是每个 pod 1 - 我可以将 cronjob 保留在集群级别吗,我已经在这里阅读了相关内容https://kubernetes.io/docs/concepts/workloads/controllers/cron-工作/ 这能解决问题吗?

2 - 我用谷歌搜索,发现其他选项是运行一个 Cronjob,它将安排一个作业完成,这会有所帮助,但不确定它的真正含义。

预先感谢您抽出时间阅读它。

drc*_*der 12

根据我对你的问题的理解,你看起来有以下两种选择(至少) -

  1. 如果您继续在 springboot 主应用程序中保留调度逻辑,那么您可能需要探索像shedlock这样的东西,它有助于确保您通过应用程序代码调度的作业仅通过外部锁提供程序(如 MySQL、Redis 等)执行一次。代码在多个节点上运行(或者在您的情况下是 kubernetes pod)。
  2. 如果您可以将调度程序特定的应用程序代码分离到其自己的可执行进程中(即该代码可以在与主应用程序代码 pod 不同的一组 pod 中运行),那么您可以利用 kubernetes 来调度cronjobkubernetes 作业,该作业在内部创建 pod 并运行您的应用逻辑。这种方法的好处是,您可以使用本机kubernetes cronjob 参数(例如并发性和其他一些参数)来确保作业在计划时间内仅通过单个 pod 运行一次。

通过方法 (1),您可以将调度程序代码与主应用程序结合起来,并在同一个 pod 中一起运行它们。

使用方法(2),您必须将代码(在调度程序中运行)与整个应用程序代码分开,将其容器化到自己的映像中,然后使用此新映像配置 kubernetes cronjob 计划,参考官方指南示例kubernetes cronjob best实践由我创作,但可以找到其他示例)。

这两种方法都有各自的优点和缺点,因此您可以评估它们以最适合您的需求。

  • 欢迎来到 Stack Overflow,感谢您的贡献。如果您要引用自己的文章,请务必阅读[如何不成为垃圾邮件发送者](https://stackoverflow.com/help/promotion),以确保您没有违反 Stack Overflow 的自我推销政策。至少,您需要透露您是文章参考文献的作者。 (2认同)
  • 感谢 @JeremyCaney 分享最佳实践,我在 Stack Overflow 上交互时一定会遵守这些最佳实践。只是为了确认,我试图通过提供潜在的选项和有用的外部链接来回答这个问题,即使问题中没有共享代码示例并且OP正在寻找可用的选项作为答案。我已经表明我给出的链接之一是由我创作的,并且还提到 OP 可以免费检查其他示例。 (2认同)