2016-03-31 8 views
4

私は、内部使用のために長年にわたるクエリWebアプリケーションを構築しています。フラスコでのバックグラウンドデーモンの起動

私の目標は、世界的な辞書オブジェクトを更新するサーバーの起動時に起動するデーモンプロセス、フラスコのアプリを持っていることです。

私は、この多くの方法を達成しようとしたとどれも成功していないように私は必ずしも、投稿するすべてのサンプル・コードを持っていません。

デーモンは、すべてのデータベース・インスタンスをループにスレッドプール(multiprocessing.Pool)を作成し、それらの上にカップルのクエリを実行します。

私はこれを(現在、フラスコ開発サーバーを使用して)どのように試して実装しても、アプリケーションをロックし、実行中は何も実行できないようです。私はたくさんのドキュメンテーションを通して読書を試みましたが、いつものように他の多くの知識が仮定され、私は圧倒的に終わります。

私は「フラスコスタートアップルーチン」とそれに類するものを探し求めていますが、何も見つかっていないので、誰かが何かガイダンスを提供できるかどうかは疑問です。これをサーバに配備すると、私の.wsgiファイルにいくつかの起動デーモンを定義することができるかもしれませんが、それまではローカルでこれを行う方法がありますか?私は一般的な使用のためにそれを押し出すとき、それは正しいアプローチですか?

それ以外の場合は、必要なクエリを実行するpythonスクリプトを連続して実行し、MongoDBインスタンスまたは何かにダンプするcronジョブを設定することを考えていました。 Flaskアプリのサーバー側のすべてのクエリはサーバーをロックするだけなので、それ以外は何もできません - 別名:情報に対処できず、スパイダーなどを殺すことはできません)

私の脳は何日も回転しています。

from flask import Flask 
from celery import Celery 

app = Flask(__name__) 
app.config['CELERY_BROKER_URL'] = 'amqp://[email protected]//' 
app.config['CELERY_RESULT_BACKEND'] = 'amqp://[email protected]//' 

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

クエリの複雑さによっては、2番目のスレッドでクエリを実行することもできます。 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() 
0

まあ、すべての最初:自分でこの問題を解決しようとしないでください:スレッドやマルチプロセッシングのいずれかの種類を使用していません。どうして?後であなたがスケールアップしたいので、最良の方法はサーバーにこれを任せておくことです - gunicorn、uwsgi。あなた自身でこれを処理しようとすると、これらのサーバーの仕組みと非常によくぶつかるでしょう。

代わりに、非同期タスクを処理するワーカープロセスで要求とメッセージキューを処理するサービスを1つ使用する必要があります。このアプローチはスケーリングの方がより優れています。

あなたの質問から、それはあなたが答えのためではなく、指導のために見ていないようだ、ここを見て: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ワーカー/タスクワーカー/セロリソリューションスケールということです唯一のボトルネックはデータベースであるため、代替案よりはるかに優れています。

+0

スケーリングは、<10人で使用される内部ツールであるため、このような問題はありません。しかし、セロリは面白いオプションのように見えます!それをチェックしましょう! – Jacob

+0

または[RQ](http://python-rq.org/)、これは素晴らしいです。 –

+0

@Jacobスケーリングは今のところ問題ではないかもしれませんが、最初から正しく処理する方が良いです... –

関連する問題