运行相同 Django 管理命令的重叠 cron 作业:有问题吗?

Overlapping cron job that runs the same Django management command: problematic?

我有一个 运行 是 Django 管理命令的定期 cron 作业。该命令与 ORM 交互,使用 sendmail 发送电子邮件,使用 Twilio 发送 SMS。 cron 作业可能会开始重叠。换句话说,当下一个作业开始到 运行 时,该作业(即 运行 的此命令)可能仍在执行。这会导致任何问题吗? (我不想等待管理命令完成执行,然后再使用 cron 运行管理命令)。

编辑:

管理命令的最开头获取命令 运行 时的时间戳。至少,这个时间戳需要准确。如果命令的其余部分不等待上一个 cron 作业完成 运行ning 就好了,但这并不重要。

编辑 2:

cron 作业只从数据库读取,不写入。当 cron 作业 运行ning 时,应用程序必须继续工作。应用程序从数据库读取和写入。

我对 cron 的理解是它会 fork 出一个作业作为后台进程,允许多个作业同时 运行。如果第二份工作取决于第一份工作(如果第二份工作是 运行 由第一份工作提供的汇总数据的每日报告等...),这可能会出现问题。如果您不希望它们同时 运行,有解决方法:

How to prevent the cron job execution, if it is already running.

Will Cron start a new job if the current job is not complete?

是的。这肯定会引起问题。您有 a race condition. If you wish, you could acquire a lock somehow on a critical section 这将阻止下一次调用进入一段代码,直到命令的第一次调用完成。您可以对基础数据进行行锁定或 table 锁定。

假设您正在使用具有特定锁定语法(依赖于数据库)的 MySQL 并且您拥有此模型:

class Email(models.Model):
    sent = models.BooleanField(default=False)
    subj = models.CharField(max_length=140)
    msg = models.TextField()

您可以像这样创建一个锁对象:

from django.db import connection
[...]
class EmailLocks(object):
    def __init__(self):
        self.c = connection.cursor()
    def __enter__(self):
        self.c.execute('''lock tables my_app_email write''')
    def __exit__(self, *err):
        self.c.execute('unlock tables')

然后锁定 所有 关键部分,例如:

with EmailLocks():
    # read the email table and decide if you need to process it
    for e in Email.objects.filter(sent=False):
        # send the email
        # mark the email as sent
        e.sent = True
        e.save()

锁定对象将在退出时自动解锁 table。此外,如果您在代码中抛出异常,table 仍将解锁。

所以你有一个运行 django 管理命令的 cron,你不希望它们重叠。

您可以使用 flock,它会生成一个锁定文件并在执行 cron.If 后将其删除第二个 cron 在第一个 cron 结束之前启动它会看到一个锁文件已经创建,因此不执行第二个。

下面是我使用的cron:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/bin/python /home/txuser/dev/Project1/projectnew/manage.py flocktest

您可以用它做很多事情。 more on this