我有一个在Docker上运行的Django应用程序。运行docker容器时,我正在尝试启动APScheduler调度程序。
我创建了一个调度程序,然后简单地将它添加到一个名为test1的工作中,然后将电子邮件发送到我的地址。
这是我运行容器时启动的Python脚本。
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler
#scheduler = BlockingScheduler()
scheduler = BackgroundScheduler()
def test1():
... (code to send email)
scheduler.add_job(test1, 'interval', seconds = 20)
scheduler.start()
这是我通过两种调度程序获得的结果:
由于电子邮件是在两种情况之一中发送的,所以我认为问题与Django和Docker无关,而仅与APScheduler有关。我做了研究,但是找不到为什么BackgroundScheduler无法像我阅读的教程那样工作,开发人员以与我相同的方式设置了调度程序。
任何帮助将不胜感激,谢谢!
更新1
我尝试了以下两项操作,都使BackgroundScheduler的行为类似于BlockingScheduler(这不是我想要的)
1)初始化调度程序实例时,将守护程序选项设置为False:
scheduler = BackgroundScheduler(daemon = False)
2)“尝试使主线程保持活动状态”,如以下内容所述:
how-do-i-schedule-an-interval-job-with-apscheduler
apscheduler-inside-a-class-object
我在scheduler.starts()之后添加了此代码:
while True:
time.sleep(1)
scheduler.shutdown()
更新2
当我尝试在单个Python文件中(在任何应用程序上下文之外)设置BackgroundScheduler时,效果很好:
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
def test1():
print('issou')
scheduler = BackgroundScheduler()
scheduler.start()
scheduler.add_job(test1, 'interval', seconds=5)
print('yatangaki')
首先打印“ yatangaki”,然后每5秒钟打印一次“ issou”,所以一切似乎都很好。
更新3
现在,我尝试在不使用Docker的情况下,使用python manage.py runserver
在本地运行的Django应用上启动调度程序。
它运行良好:发送电子邮件,我可以访问应用程序的主视图。
注意:BackgroundScheduler由称为start_test1
的函数启动。在此应用程序中,我在顶级urls.py文件中运行start_test1
。在另一个应用程序上(我要在Docker上运行的那个应用程序,这是我最终要使用的应用程序),start_test1
是在Python脚本中启动的,而该脚本本身是在我运行的.sh文件中触发的通过CMD Docker命令。
答案 0 :(得分:0)
看来,这一切都是在何处启动调度程序和添加作业的。
在我最初的工作中(将代码放入.sh文件中),BackgroundScheduler启动了,但是 Python脚本在运行后立即结束,因为它没有阻塞行为,并且sh。文件不是真正属于应用程序的一部分(它由Dockerfile使用,而不是由应用程序使用)。
我最终在这里找到解决方案: execute-code-when-django-starts-once-only 我的应用程序内部没有apps.py文件,因此我创建了一个文件并按照该线程中的说明进行操作。
现在工作正常。