简体   繁体   English

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

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

I have a recurring cron job that runs a Django management command. 我有一个运行Django管理命令的定期cron作业。 The command interacts with the ORM, sends email with sendmail, and sends SMS with Twilio. 该命令与ORM交互,通过sendmail发送电子邮件,并通过Twilio发送SMS。 It's possible that the cron jobs will begin to overlap. Cron作业可能会开始重叠。 In other words, the job (that runs this command) might still be executing when the next job starts to run. 换句话说,当下一个作业开始运行时,该作业(运行此命令)可能仍在执行。 Will this cause any issues? 这会引起任何问题吗? (I don't want to wait for the management command to finish executing before running the management command again with cron). (我不想等待管理命令完成执行,然后再使用cron运行管理命令)。

EDIT: 编辑:

The very beginning of the management command gets a timestamp of when the command was run. 管理命令的最开始会获得命令运行时间的时间戳。 At a minimum, this timestamp needs to be accurate. 至少,此时间戳需要准确。 It would be nice if the rest of the command didn't wait for the previous cron job to finish running, but that's non-critical. 如果命令的其余部分不等待上一个cron作业完成运行就很好了,但这并不重要。

EDIT 2: 编辑2:

The cron job only reads from the DB, it doesn't write to it. cron作业仅从数据库读取,而不会写入数据库。 The application has to continue to work while the cron job is running. 在cron作业运行时,应用程序必须继续工作。 The application reads and writes from the DB. 该应用程序从数据库读取和写入。

My understanding of cron is that it will fork off a job as a background process, allowing multiple jobs to run at the same time. 我对cron的理解是,它将把一个作业作为后台进程派生出来,从而允许多个作业同时运行。 This can be problematic if the second job depends on the first job to be done (if the second is running a daily report of aggregated data provided by the first job etc...). 如果第二项工作依赖于要完成的第一项工作(如果第二项正在运行由第一项工作提供的汇总数据的每日报告等),则可能会出现问题。 If you don't want them to run concurrently, there are workarounds to that: 如果您不希望它们同时运行,则有一些解决方法:

How to prevent the cron job execution, if it is already running . 如果cron作业已经在运行,则如何防止其执行

Will Cron start a new job if the current job is not complete? 如果当前作业未完成,Cron会开始新的作业吗?

Yes. 是。 This could definitely cause issues. 这肯定会引起问题。 You have a race condition . 你有种族状况 If you wish, you could acquire a lock somehow on a critical section which would prevent the next invocation from entering a section of code until the first invocation of the command finished. 如果需要,您可以以某种方式在关键部分上获得一个锁,这将阻止下一次调用输入代码部分,直到命令的第一次调用完成。 You may be able to do a row lock or a table lock for the underlying data. 您可能可以对基础数据进行行锁定或表锁定。

Let's presume you're using MySQL which has specific lock syntax (DB dependent) and you have this model: 假设您正在使用具有特定锁定语法(取决于数据库)的MySQL,并且具有以下模型:

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

You can create a lock object like this: 您可以这样创建一个锁对象:

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')

Then lock all of your critical sections like: 然后锁定所有关键部分,例如:

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()

The lock object will automatically unlock the table on exit. 锁定对象将在退出时自动解锁表。 Also, if you throw an exception in your code, the table will still be unlocked. 另外,如果在代码中引发异常,则该表仍将被解锁。

So you have a cron that runs django management command and you dont want them to overlap. 因此,您具有运行django管理命令的cron,并且您不希望它们重叠。

You can use flock , Which generates a lockfile and deletes it after executing the cron.If the second cron starts before the first one has ended it will see that there a lockfile already created and thus not execute the second one. 您可以使用flock生成一个锁文件并在执行cron之后将其删除。如果第二个cron在第一个cron结束之前启动,它将看到已经创建了一个锁文件,因此不执行第二个cron。

Below is the cron i used: 以下是我使用的Cron:

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

There is lot more you can do with this. 您可以做更多的事情。 more on this 更多关于这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM