Flaskにおける複数リクエストの並列処理


Python 3.3.5 + Flaskでサーバアプリを作っています。

## 内容

FlaskにHTTPリクエストを送ると即座にレスポンスを返してくれますが、

  * 2つ以上のリクエストを同時に送る

もしくは

  * 早かった方のリクエストの処理中に続けてリクエストを送る

といった事をすると、遅かった方のリクエストのレスポンスは早かった方へのレスポンスが完了するまで待たされます。

単一スレッドで処理しているだからだと思われますが、これをFlaskで並列処理できる方法はありませんでしょうか。

## テストに使ったコード

[code]

    if __name__ == '__main__':
        app = Flask(__name__)
        app.config.update(PROPAGATE_EXCEPTIONS = True)
    
        @app.route('/')
        def greet():
            n = randrange(1, 10)
            sleep(n)
            return 'Hello world! I slept {0}[s].'.format(str(n))
    
        app.run()
    
[/code]

これは、リクエストが飛んできたら乱数を元に1 - 10秒待ち何秒待ったか返すコードです。

ブラウザのタブを2つ用意し、両方素早くlocalhost:5000へアクセスすると、先にアクセスした方にレスポンスが返ってきてから後の方の待つフェーズが始まることが待ち時間からわかります。

もしFlaskが並列でレスポンスを返すことができたら、待ち時間の乱数が小さかったほうが先に返ってくるはずです。




flask.Flask.runのオプションにprocessesまたはthreadedを指定する事で可能だと思います。
windows環境ではforkがないためproessesはエラーとなりました。

[code]

        app.run(processes=3)
    
[/code]

または

[code]

        app.run(threaded=true)
    
[/code]

別のブラウザから同時アクセスして同時に処理されることを確認しました。

runのオプションはwerkzeugに渡されるそうなのでoptionsに関してはWerkzeugのドキュメントを参照する必要があります。

>   * options – the options to be forwarded to the underlying Werkzeug server.
> See werkzeug.run_simple() for more information.
>

[Flask.run
(bitbucket.org)](http://a2c.bitbucket.org/flask/api.html?highlight=flask#flask.Flask.run)  
[werkzeug parameters (pocoo.org)](http://werkzeug.pocoo.org/docs/0.9/serving/)




Flask.run() は開発用サーバーであり、実際にサービスを提供するために利用するためのものではありません。 一般的な構成には、

  * 静的ファイル配信を nginx で行い、 nginx からリバースプロキシして gunicorn か uWSGI で Flask アプリを動かす。
  * Apache と mod_wsgi を使う。

といった選択肢があります。個人的には前者がお勧めです。

