Heroku上的Flask应用程序,多名枪手工作者-避免重复的后台线程

时间:2019-09-08 16:57:25

标签: multithreading heroku flask gunicorn

我已在生产环境中将Flask应用程序部署到Heroku,并在我的Procfile:web: gunicorn --chdir src/ server:app中以gunicorn开头。我有一些启动应用程序的后台线程(一个调度程序,它每周发送一封电子邮件,一个“ pinger”线程来不断ping通该应用程序,以使其不会在Heroku上休眠)。根据我的日志,似乎这些线程中的每个线程都是为 each worker启动的。即,如果我将Procfile更改为web: gunicorn --workers=1 --chdir src/ server:app,那么我将只有一个pinger实例,但是如果我未指定1个worker,则为2个实例(假设Heroku将WEB_CONCURRENCY环境变量设置为2,因为它看起来像gunicorn如果没有提供工人)。同样,如果我有3个工作线程,则有3个pinger线程。

这只是该调度程序线程的一个问题,我只需要一个实例(因此它不会多次向人发送相同的电子邮件)。但是,这些后台线程中的任何一个都不需要多个实例。

我想知道是否有任何简单/优雅的方法来让数量众多的枪械工人工作,但是每个背景线程的实例恰好是一个烧瓶应用启动。

在我意识到这是决定线程数量的工作人员数量之前,我只是假设我必须处理每个线程的2个实例,所以我的解决方案(要有点hacky?)是使用config /添加数据库表ID列。因此,我将为调度程序ID提供一个正在运行的整数,并且即使它是偶数也不会启动该线程。

即伪代码:

Flask app initialization
start_scheduler()

def start_scheduler():
    get database value for scheduler_id, locking that table
    scheduler_id += 1
    if scheduler_id % num_workers == 0:
        actually build and start scheduler thread

所以现在,该应用程序仅在恰好有2个工作程序的情况下/代码与工作程序的数量匹配时才起作用-我认为这不是最佳设计。我也只需一个工人或采用当前的解决方案就可以生存-我只是想知道是否有更好的方法或缺少的Flask / Heroku / Gunicorn东西会使这变得容易。

我还没有完全解决这个想法-但是我不确定将后台线程初始化拉入一个单独的python脚本并以与主线程分开的单个工作程序启动它们是多么容易应用程式。我还希望它们在主程序退出时被杀死。

0 个答案:

没有答案