我在Django中设置了多个克朗。在每个CronJob中,我都设置了ALLOW_PARALLEL_RUNS = False
。为了运行克朗,我使用了Linux crontab
,如下所示:
*/1 * * * * /home/social/centralsystem/venv/bin/python3.6 /home/social/centralsystem/manage.py runcrons
运行一段时间后(例如2个月后),我看到许多运行的同名客户在服务器上造成了很多负载。我的问题是造成这种情况的原因是什么?
我的cron类的一个示例是:
class UserTaskingCronJob(CronJobBase):
ALLOW_PARALLEL_RUNS = False
RUN_EVERY_MINS = 5
schedule = Schedule(run_every_mins=RUN_EVERY_MINS)
code = 'user_tasking'
def do(self):
args = {
'telegram': {
'need_recrawl_threshold': 60 * 2,
'count': 100,
},
'newsAgency': {
'need_recrawl_threshold': 10,
'count': 100,
},
'twitter': {
'need_recrawl_threshold': 60 * 4,
'count': 500
},
}
for social_network in ['telegram', 'newsAgency', 'twitter']:
user_queuing(
SOCIAL_USERS_MODEL[social_network],
social_network,
args[social_network]['need_recrawl_threshold'],
args[social_network]['count'],
)
答案 0 :(得分:2)
您的cronjob每分钟运行一次。
有关说明,请参见here
Cron分为:
minute
hour
day(month)
month
day(week)
斜线表示步长值。
在您的情况下,它将以1分钟为单位执行。即每分钟。
*/1 * * * *
答案 1 :(得分:1)
如果您有许多不同的任务在不同的时间段运行,则必须谨慎使用django-cron。 runcrons
按顺序获取所有cron类,并按顺序运行它们。完成后,它也只会将cron(成功与否)记录到数据库中。我认为django-cron可以通过在开始时保存cron日志(并检查是否已经有正在运行的任务)来进行改进,但是如果运行多个作业而不是一个长时间的作业,那仍不能排除重叠。
您每分钟都在运行runcrons
,因此在这些情况下,您会遇到麻烦:
在两种情况下,某些任务都不会及时登录到数据库中,并且在它们运行时,下一个runcrons
命令将再次启动它们。
为避免这种情况,请执行以下操作:
runcrons
命令,每个命令都包含一个cron类列表,以确保列表的总运行时间少于1分钟,例如*/1 * * * * ./bin/python3.6 manage.py runcrons "my_app.crons.FirstCron" "my_app.crons.SecondCron"
*/1 * * * * ./bin/python3.6 manage.py runcrons "my_app.crons.ThirdCron"
*/10 * * * * ./bin/python3.6 manage.py runcrons "my_app.crons.LongCron"
答案 2 :(得分:0)
我建议您为每个社交网络创建一个锁定文件,并检查您的最后一个收集器是否完成。例如,在代码的开头添加/tmp/telegram.lock
(如果存在,则停止该作业),然后在代码的末尾将其删除。每次您要开始新工作时,请检查是否存在旧锁。
答案 3 :(得分:0)
我发布了最终解决方案,以便其他任何人都可以使用它。
首先,您应该知道由于django-cron
错误,您不应期望它会阻止单个cron
的并行运行。因此,为了防止并行运行,您应该为每个分支都编写一个单独的Linux crontab
。
第二,您应该使用某种锁定方式来防止crontab多次运行单个cron。我建议使用flock
答案 4 :(得分:0)
Django cron默认情况下使用缓存来维护当前正在进行的作业的状态,因此除非指定为并行运行,否则它不会多次执行任务。
如果您在Django应用中设置了缓存,则无需担心,并在crontab
中多次拆分命令
有关更多信息,您可以检查它here