0

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

编辑:

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

编辑2:

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

4

3 回答 3

2

我对 cron 的理解是,它将一个作业作为后台进程分叉,允许多个作业同时运行。如果第二项工作依赖于要完成的第一项工作(如果第二项工作正在运行第一项工作提供的汇总数据的每日报告等),这可能会出现问题。如果您不希望它们同时运行,则有一些解决方法:

如果 cron 作业已经在运行,如何防止它执行

如果当前作业未完成,Cron 会开始新作业吗?

于 2015-11-23T18:52:28.410 回答
1

是的。这肯定会导致问题。你有一个竞争条件。如果您愿意,您可以以某种方式在关键部分上获取锁,这将阻止下一次调用进入一段代码,直到第一次调用命令完成。您可能能够为基础数据执行行锁或表锁。

假设您使用的是具有特定锁定语法(依赖于数据库)的 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()

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

于 2015-11-23T18:53:10.010 回答
0

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

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

以下是我使用的 cron:

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

你可以用这个做更多的事情。 更多关于这个

于 2018-02-25T07:38:44.747 回答