Django 2使用runserver启动生成两个scheduler实例问题咨询
两个进程各自启动scheduler的方案不可行,会导致定时任务重复执行:你设定的每分钟拉取数据的任务会同时被两个调度器触发,一分钟内执行两次,容易产生重复数据、资源竞争等问题,绝对不推荐。
以下是不同场景下的解决方案:
开发环境临时解决方案
- 启动runserver时添加
--noreload参数,关闭代码自动重载功能,Django就只会启动1个进程,scheduler自然只会初始化一次:
缺点是修改代码后服务不会自动重启,适合临时调试用。py manage.py runserver --noreload - 增加进程判断逻辑,仅在Django主进程中启动scheduler,不影响代码自动重载功能,修改
ApiConfig的ready方法即可:from django.apps import AppConfig import os class ApiConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'api' def ready(self): # 只有Django主进程的RUN_MAIN环境变量为true if os.environ.get('RUN_MAIN') == 'true': import api.scheduler as scheduler scheduler.start()
生产环境最佳实践
生产环境下不管你用Gunicorn还是uWSGI部署Django,默认都会启动多个worker进程,上面的环境变量判断逻辑会失效。最稳定的方案是将定时任务和web服务完全解耦:
- 单独写一个Django自定义命令来启动调度器,独立于web进程单独运行,整个环境只会有1个scheduler实例,从根源上避免重复执行问题,无需处理多进程共享逻辑。
- 如果确实需要多进程共用调度器,可给APScheduler配置Redis/数据库作为持久化任务存储,同时给任务添加唯一ID和分布式互斥锁,避免重复触发,但该方案实现复杂度较高,优先推荐独立进程部署的方案。
内容的提问来源于stack exchange,提问作者Aniket Banyal
相关产品推荐
相关产品推荐

