Python 2.7中同时处理多个POST请求

时间:2019-03-27 07:56:51

标签: python python-2.7 flask concurrency tornado

我有一个龙卷风服务器,监听6789端口,以查询"/train""/predict"上的POST请求。训练方法最多可能需要3个小时才能完成,而预测方法可能会在2分钟后返回。我希望同时处理它们。因此,即使正在运行“ / train”,如果对“ / predict”的POST请求到达,它也可以同时处理并返回其输出,而无需等待“ / train”完成。

我尝试使用ThreadPool,但是它仍然不能同时运行。

我现在的代码如下。它起作用,但是如果要求训练,然后要求预测。它在处理预测之前等待火车完成。假设存在训练和预测功能,并且不带任何参数。

import logging
import time
import threading
from multiprocessing.pool import ThreadPool
import flask
from tornado import wsgi, httpserver, ioloop
from flask import Flask
from train_script import train
from predict_script import predict
app = Flask(__name__)


@app.route("/train", methods=['POST'])
def train_run():
    payload = flask.request.get_json(silent=True)
    if payload is not None:
        try:
            async_result = pool.apply_async(train)
            response = async_result.get() 
            resp = flask.jsonify(response)
            resp.status_code = 200
        except Exception as ex:
            resp = flask.jsonify({"status": "Failure"})
            resp.status_code = 500
    else:
        resp = flask.jsonify({"status": "Failure"})
        resp.status_code = 500
    return resp

@app.route("/predict", methods=['POST'])
def predict_run():
    payload = flask.request.get_json(silent=True)
    if payload is not None:
        try:
            async_result = pool.apply_async(predict)
            response = async_result.get() 
            resp = flask.jsonify(response)
            resp.status_code = 200
        except Exception as ex:
            resp = flask.jsonify({"status": "Failure"})
            resp.status_code = 500
    else:

        resp = flask.jsonify({"status": "Failure"})
        resp.status_code = 500
    return resp


if __name__ == "__main__":
    port = 6789
    http_server = httpserver.HTTPServer(wsgi.WSGIContainer(app))
    pool = ThreadPool(processes=10)# Expects max concurrent requests to be 10
    http_server.listen(port)
    logging.info("Tornado server starting on port {}".format(port))
    ioloop.IOLoop.instance().start()

1 个答案:

答案 0 :(得分:0)

Tornado的WSGIContainer不支持任何类型的并发。在不使用Flask或WSGI的情况下使用Tornado的RequestHandler接口,或者在gunicornuwsgi上使用Flask。通过将Tornado与WSGI框架结合使用,您几乎一无所获,并且损失很多,因此这仅在某些特殊情况下有用。