aspscheduler+uwsgi定时任务执行多次

1. 问题描述

当uwsgi设置多进程的时候,多个进程都会执行定时任务,导致同一个任务会执行多次。网上找了很多文章,大都是用数据库,或者锁的形式解决。
感觉都不是特别好的方式,决定换一种方式来设置定时任务。
在此记录一下,下次使用其他设置定时任务的方式。

 2. 我的实现思路

1. 使用数据库锁(使用redis性能会更好)
    在数据建一张表:create table cron_job(id serial, job_name varchar(255))
    create index idx_job_name on cron_job(job_name)  # 不加索引后面会锁表

2. 执行任务之前先去数据库获取锁
    select job_name from cron_job where job_name='你的任务名称' for update;  # job_name需要先插入到数据库,每个job的name需要用不同的name分开
    如果能获取锁,就去执行任务,没有在一定时间获取锁的进程设置超时,自动结束
    执行完成任务之后,释放锁
3. 优化
  我们可以新加一个下次执行时间(next_exec_time)的字段,在获取到锁之后,判断该条记录的是否小于当前时间,如果小于则执行任务,如果不小于,则终止任务,等待下次时间到了之后触发。
4. 注意,使用数据库的时候,一定要注意释放锁,不然连接一直不断开,下次执行任务就无法获取锁

 3. 解决办法

时隔三年,终于找到了问题的原因。
django服务启动多进程,是对服务本身的服务能力开启的(具体的我解释不清楚),对于一些启动项,像是settings等项目级别的文件在启动项目的时候都是只加载一次,全局通用。而我的定时任务,调用start()方法是在crontab/views下执行的,因此使用uwsgi开启多个进程的时候,定时任务也会被开启多个。
解决方法,将start方法在wsgi文件中执行。
在你需要在django启动之前做的一些初始化,比如清空redis内存,或者加载一些其他内容。
hmmm...这个方法目前感觉好像不太行,回头试试再说

 4. apscheduler常用:https://blog.csdn.net/weixin_53287520/article/details/134843170

posted @ 2021-07-24 11:44  10132714  阅读(307)  评论(0编辑  收藏  举报