2014-09-03 80 views
21

我正在建立一个网站,向访问者提供一些信息。这些信息在后台汇总,每5秒钟轮询一对外部API。我现在工作的方式是使用APScheduler作业。我最初首选APScheduler,因为它使得整个系统更容易移植(因为我不需要在新机器上设置cron作业)。我开始轮询功能如下:如何在Python Flask框架中运行循环任务?

from apscheduler.scheduler import Scheduler 

@app.before_first_request 
def initialize(): 
    apsched = Scheduler() 
    apsched.start() 

    apsched.add_interval_job(checkFirstAPI, seconds=5) 
    apsched.add_interval_job(checkSecondAPI, seconds=5) 
    apsched.add_interval_job(checkThirdAPI, seconds=5) 

这有点儿工作,但有一些麻烦吧:

  1. 对于初学者来说,这意味着区间作业的瓶上下文之外运行。到目前为止,这并没有太大问题,但是当调用一个端点失败时,我希望系统给我发一封电子邮件(说“嗨调用API X失败”)。因为它不在Flask上下文中运行,所以投诉flask-mail无法执行(RuntimeError('working outside of application context'))。
  2. 其次,我不知道这是怎么回事的行为时,我不使用内置调试服务器在了烧瓶中,但与生产服务器可以说4名工人。它会四次开始每个工作吗?

总而言之,我觉得应该有更好的方式来运行这些重复的任务,但我不确定如何。有没有人有这个问题有趣的解决方案?欢迎所有提示!

[编辑] 我刚刚阅读了关于Celery及其schedules。尽管我并没有真正看到芹菜与APScheduler有什么不同,并且它是否可以解决我的两个问题,但我想知道是否有人读过这篇文章,认为我应该在芹菜中进行更多调查?

[结论] 大约两年后,我正在读这本书,我想我可以让你们知道我最终的结果。我认为@BluePeppers正确地说我不应该与Flask生态系统紧密联系。所以我选择了使用Ansible设置的每分钟运行的常规cron-jobs。虽然这使得它更复杂一些(我需要学习Ansible并转换一些代码,以便每分钟运行一次就足够了),但我认为这更加强大。 我目前正在使用真棒pythonr-rq排队同步作业(检查API和发送电子邮件)。我刚刚发现约rq-scheduler。我还没有测试过它,但它似乎正是我首先需要做的。所以也许这是这个问题的未来读者的提示。

其余的,我只是祝你们大家美好的一天!

回答

22

(1)

可以使用app.app_context()上下文管理器来设置应用程序上下文。我想象的使用会去是这样的:

from apscheduler.scheduler import Scheduler 

def checkSecondApi(): 
    with app.app_context(): 
     # Do whatever you were doing to check the second API 

@app.before_first_request 
def initialize(): 
    apsched = Scheduler() 
    apsched.start() 

    apsched.add_interval_job(checkFirstAPI, seconds=5) 
    apsched.add_interval_job(checkSecondAPI, seconds=5) 
    apsched.add_interval_job(checkThirdAPI, seconds=5) 

或者,你可以使用一个装饰

def with_application_context(app): 
    def inner(func): 
     @functools.wraps(func) 
     def wrapper(*args, **kwargs): 
      with app.app_context(): 
       return func(*args, **kwargs) 
     return wrapper 
    return inner 

@with_application_context(app) 
def checkFirstAPI(): 
    # Check the first API as before 

(2)

是的,它仍然可以工作。唯一的(重要的)区别是您的应用程序不会直接与世界通信;它将通过一个反向代理或者通过fastcgi/uwsgi /任何东西进行。唯一值得关注的是,如果您有多个应用程序实例启动,那么将创建多个调度程序。为了管理这个,我建议你将你的后端任务移出Flask应用程序,并且使用一个专门用于定期运行任务的工具(即Celery)。这样做的缺点是你不能使用像Flask-Mail这样的东西,但是imo,与Flask生态系统紧密联系并不是太好;使用Flask-Mail通过标准的非Flask邮件库获得什么?

另外,与具有一个单一的Web应用程序相比,打破您的应用程序可以更容易地扩展单个组件,因为需要容量。

+0

谢谢你的详细答案。最后一件事;由于APScheduler工作得很好,你认为在APScheduler上使用Celery会有什么优势?你会选择什么?为什么? – kramer65 2014-09-03 09:18:23

+0

Well芹菜为您提供的不仅仅是简单的调度。据说,我对APScheduler知之甚少,现在阅读文档,看起来非常好。 – BluePeppers 2014-09-03 09:20:06

+0

我觉得这篇文章非常有用。但我想问一下,我正在为我的应用程序使用SQL数据库,APScheduler或Celery更适合使用哪个数据库?我可以在Celery看到redis。我是否选择APScheduler? – clementiano 2015-11-19 10:35:37

相关问题