Flask 作为代理在部署到龙卷风时不起作用

Flask as proxy doesn't work when deployed to tornado

我编写了一个 flask 应用程序作为一种代理,以分析通过它的数据并提供一个网页,我可以在其中获得结果。使用 flask 附带的默认开发服务器时,一切似乎都很顺利,比如使用:

app.run()

但是当我尝试将应用程序部署到服务器时,例如 tornado 或 Python 标准库中的 wsgiref.simple_server 使用:

from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from app import app

http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()

from wsgiref.simple_server import make_server
from app import app

httpd = make_server('', 5000, app)
httpd.serve_forever()

这两种方式导致在请求之前获得 200 OK 时出现 404 错误。

我的应用程序收到的请求,因为它充当代理,在请求行中带有绝对 urls,如 POST http://example.com/test HTTP/1.1。当我使用开发服务器时,此请求通常由 /test 下注册的函数处理,例如:

@app.route('/test', methods=['GET', 'POST'])
def handle_test():
    ...

request.url,正如我检查的那样,是 http://example.com/test

使用其他两种方式时,请求由代码为 404 的错误处理程序处理,并且永远不会调用 handle_test() 函数。问题的request.urlhttp://example.com/http://example.com/test,绝对不是我想要的

所以我想知道:

  1. 是什么将 url 改成了错误的,这是什么时候发生的。
  2. 为什么应用程序在默认开发服务器和像 tornado 这样的服务器上表现不同。
  3. 当然,如何解决这个问题。

谢谢!

Tornado 目前不支持代理式请求;见 https://github.com/tornadoweb/tornado/issues/1036

Tornado 的 WSGIContainer 对于代理来说也是一个糟糕的选择,因为它的单线程并发模型(参见 http://www.tornadoweb.org/en/stable/wsgi.html#tornado.wsgi.WSGIContainer)。即使上述错误得到修复,您的代理也会表现不佳。我建议使用多线程 WSGI 服务器(如 gunicorn 或 uwsgi,尽管我不知道它们是否支持代理式请求)或将代理重写为原生 Tornado 应用程序(不带 flask)以利用异步功能。