【问题标题】:Job is not performed by APScheduler's BackgroundScheduler作业不是由 APScheduler 的 BackgroundScheduler 执行的
【发布时间】:2018-08-01 15:07:21
【问题描述】:

我有一个在 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()

这是我使用两种调度器得到的结果:

  • BlockingScheduler:调度程序工作,我每 20 秒收到一封电子邮件。但是我无法访问该应用程序。由于 BlockingScheduler 的性质,我认为这是正常的。

screenshot1

screenshot2

  • BackgroundScheduler:访问应用程序没有问题。但是,我没有收到任何电子邮件。

由于电子邮件是在两种情况之一中发送的,我猜这个问题既不是 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

现在我尝试在我使用 python manage.py runserver 在本地运行的 Django 应用上启动调度程序,而不使用 Docker。

完美运行:电子邮件已发送,我可以访问应用程序的主视图。

注意:BackgroundScheduler 由一个名为start_test1 的函数启动。在这个应用程序中,我在顶级 urls.py 文件中运行 start_test1。在另一个应用程序上 - 我使用 Docker 运行的应用程序,这是我最终要使用的应用程序 - start_test1 在 Python 脚本中启动,它本身在 .sh 文件中触发,我通过CMD Docker 命令。

【问题讨论】:

  • “但是我无法访问应用程序”你的意思是什么?
  • 我的意思是当我转到 localhost:8000 时,我得到“无法访问此站点,localhost 拒绝连接”,而我使用 BackgroundScheduler 时并非如此。我将在我的帖子中添加屏幕截图以使其更清晰
  • 您是否在终端控制台中看到任何其他内容,您在哪里执行了 manage.py 运行服务器?
  • 哦,我看到了你的截图,在第一个截图中你的 url 错误,应该是:localhost:8000 而不是 localhost8000.com 我猜
  • BackgroundScheduler 使用线程池作为执行器,所以问题可能与线程有关。

标签: python django docker apscheduler


【解决方案1】:

看来这完全是关于在哪里启动调度程序并添加作业。

在我最初所做的(将代码放在 .sh 文件中)中,BackgroundScheduler 启动但 Python 脚本在运行后立即结束,因为它没有阻塞行为并且嘘。文件实际上并不是应用程序的一部分(它由 Dockerfile 使用,而不是由应用程序使用)。

我最终在这里找到了解决方案: execute-code-when-django-starts-once-only 我的应用程序中没有 apps.py 文件,所以我创建了一个并按照此线程中的说明进行操作。

现在可以正常使用了。

【讨论】:

  • 我也有这个问题,我在urls.py里放了apscheduler启动功能,但是过一段时间job还是停止工作。
【解决方案2】:

我有一个类似的问题,但它只是通过不阻止工人得到解决:

# working:
def worker():

    phone_elm = ....
    thread = threading.Thread(target=work, args=(phone_elm,))
    thread.start()

# not working:
def worker():
    phone_elm = ....
    work(phone_elm)

scheduler2 = BackgroundScheduler(timezone="Asia/Kolkata")
# schedule scanning running of folder's running file
scheduler2.add_job(worker, 'interval', seconds=15,  max_instances=5000)

scheduler1.start()

我的意思是不工作,是在 10 ~ 时间后触发它无缘无故停止,在 10 个停止后再次启动(工作退出)

也是django的一部分,但是很明显start没有退出……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多