基本上我的 cron 每 2 分钟更新一次数据库。但我需要运行另一个 cron,每 24 小时更新一次数据库。我需要确保第二个 cron(每天)运行时不存在竞争条件,即两个 cron 不能一起运行和重叠。这需要在 Kubernetes 集群中使用作业来实现。
我的解决方案是每 2 分钟运行第一个 cron,但在第二个 cron 运行时(每天)延迟 5 分钟。
欢迎任何替代解决方案。
我试图考虑几种可能性,但事情可能会出错,主要是因为您有一项工作需要每 2 分钟运行一次,让我们假设您的日常工作出于任何原因花费的时间比您预期的要多,新的 2 分钟工作将开始,但这是不可能发生的。
最好的解决方案是在代码级别解决这个问题。您可以在应用程序中创建锁以防止这些作业同时运行。
如果您确实无法在代码中提出任何解决方案来解决此问题,Kubernetes 上有一种机制可以阻止同一 cronjob 启动新作业。您可以设置标志 spec.concurrencyPolicy: Forbid,这样如果您的作业启动时间超过 2 分钟,新作业将被跳过。这不是一个全局标志,这只是每个 cronjob 的标志。
您可以使用 spec.initContainers 聚合这种可能性,并找到一种在同一个 cronjob 中运行这两个任务的方法。
spec.initContainers 是在应用程序容器之前运行的专用容器。
这是一个例子:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
concurrencyPolicy: Forbid
schedule: "*/2 * * * *"
jobTemplate:
spec:
template:
spec:
initContainers
- name: hello1
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
containers:
- name: hello2
image: busybox
args:
- /bin/sh
- -c
- DATE=`date +"%H:%M"`; if [[ $DATE == "00:00" ]]; then date; echo Hello from the Kubernetes cluster; fi
restartPolicy: OnFailure
此清单定义了一个 cronJob,它将每 2 分钟运行一次,并将启动一个 initContainer(您的 2 分钟作业),并且每 2 分钟运行第二个容器。问题是,在第二个容器中,我们有一个 shell 脚本检查是否是午夜(忽略秒数,因为我们无法确定它何时开始)。
您可能需要调整这部分代码:
DATE=`date +"%H:%M"; if [[ $DATE == "00:00" ]
假设您的第一个容器需要超过一分钟的时间来执行,它将是 00:01 并且您的第二个作业将永远不会被执行。
请告诉我这些信息和解决方案是否对您有帮助。
with *schedule: "5/2 * * * " ,您可以在这里获取配置 https://crontab.guru/#5/2__**