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

问题描述 投票:0回答:1

当前设置

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

问题

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

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

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

需要

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

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

提前感谢您抽出时间阅读它。

kubernetes cron
1个回答
13
投票

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.