在Flask应用程序中启动后台守护程序

时间:2016-03-31 20:04:32

标签: python flask python-multiprocessing

因此,我正在建立一个供内部使用的长期查询网络应用程序。

我的目标是让一个带有守护进程的烧瓶应用程序在服务器启动时启动,这将更新一个全局字典对象。

我不一定要发布任何示例代码,因为我已经尝试过这么多方法而且都没有成功。

守护进程将创建一个线程池(multiprocessing.Pool)来循环遍历所有数据库实例并对它们运行几个查询。

似乎无论我如何尝试和实现它(现在,使用烧瓶开发服务器)它都会锁定应用程序,并且在它运行时无法完成任何其他工作。我试过阅读一堆文档,但是按照惯例,我会假设很多其他知识,最后我不知所措。

我想知道是否有人可以提供一些指导,即使它可以寻找这个地方,因为我已经搜遍了所有的烧瓶启动例程'和类似的,但没有发现任何使用。似乎当我将它部署到我们的服务器时,我可能能够在我的.wsgi文件中定义一些启动守护进程,但在那之前有没有办法在本地执行此操作?当我把它推出一般用途时,这是否是正确的方法?

否则,我只是想设置一个cron作业,它连续运行一个python脚本来执行我需要的查询,并转储到MongoDB实例或其他东西,以便客户端可以简单地从中拉出(就像所有Flask应用程序服务器端的查询只是锁定了服务器,所以没有别的办法可以用 - 也就是说:不能对信息采取行动,杀死spid等等)

任何有关这方面的帮助都会有所帮助,我的大脑已经旋转了几天。

from flask import Flask
from celery import Celery

app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'amqp://guest@localhost//'
app.config['CELERY_RESULT_BACKEND'] = 'amqp://guest@localhost//'

celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)

output = 0

@app.before_first_request
def init():
    task = my_task.apply_async()

@app.route('/')
def hello_world():
    global output
    return 'Hello World! - ' + str(output)


@celery.task
def my_task():
    global output
    result = 0
    for i in range(100):
        result += i
        output = result




if __name__ == '__main__':
    app.run()

2 个答案:

答案 0 :(得分:3)

根据查询的复杂程度,您可以考虑通过第二个线程运行查询。由于GIL,您不必担心常见的数据结构对象(例如字典)是线程安全的。关于线程的一个好处是即使有一个GIL,他们通常也不会阻止在强烈的I / O期间执行的其他线程(例如查询的线程)。见2。琐碎的例子:

import threading
import time
import random
from flask import Flask

app = Flask(__name__)

data_store = {'a': 1}
def interval_query():
    while True:
        time.sleep(1)
        vals = {'a': random.randint(0,100)}
        data_store.update(vals)

thread = threading.Thread(name='interval_query', target=interval_query)
thread.setDaemon(True)
thread.start()

@app.route('/')
def hello_world():
    return str(data_store['a'])

if __name__ == "__main__":
    app.run()

答案 1 :(得分:0)

嗯,首先:不要试图自己解决这个问题:不要使用线程或任何类型的多处理。为什么?因为稍后你想扩大规模,最好的方法就是把它留给服务器 - gunicorn,uwsgi。如果您试图自己处理这个问题,很可能会碰到这些服务器的工作方式。

相反,您应该使用一个服务来处理请求和消息队列以及处理异步任务的工作进程。这种方法在扩展方面更好。

从您的问题看来,您似乎没有寻找答案,而是寻求指导,请查看此处:http://flask.pocoo.org/docs/0.10/patterns/celery/和此https://www.quora.com/Celery-distributed-task-queue-What-is-the-difference-between-workers-and-processes

这里的优点是web worker / task worker / celery解决方案比其他解决方案更好地扩展,因为唯一的瓶颈是数据库。