解决django-apscheduler和gunicorn重复运行

问题分析

最近有需求需要用到定时任务,我选择了django-apscheduler,但是在开发环境进行自测时发现同一时间运行了三次

gunicorn配置如下图,这里的cpu1,刚好启动的进程数为3

gunicorn在启动的时候开启了三个进程,但是这里的apscheduler也就启动三个,这时会造成定时任务重复运行

解决问题

网上的解决方法主要有两种:

  • gunicorn 启动的时候加上--preload参数,或者preload_app=True,默认为False
  • 第二种是使用的方式来控制

我这里也是使用锁来实现,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.conf import settings
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job
from django_redis import get_redis_connection
scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), "default")
scheduler.remove_all_jobs()
key = "lock"
redis_cli = get_redis_connection(settings.REDIS_CACHE_ALIAS)
data = redis_cli.get(key)
if data is None:
redis_cli.set(key, "lock", ex=10)
register_events(scheduler)
scheduler.start()

启动时设置一个key,后面几个进程启动发现key已设置就不启动apscheduler, 设置过期时间为启动后key的释放,这里只是一个简单实现思路,可以参考并发锁去实现。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器