本地Flask服务器上的慢速请求

Mer*_*oon 74 python flask

刚刚开始在本地服务器上使用Flask,我注意到请求/响应时间比我认为的要慢.

只需一个简单的服务器,如下所示需要近5秒才能响应.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "index"

if __name__ == "__main__":
    app.run()
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?或者这只是本地服务器的方式?

Mer*_*oon 86

好吧我明白了.Werkzeug和os的支持ipv6似乎是一个问题.

来自Werkzeug网站http://werkzeug.pocoo.org/docs/serving/:

在支持ipv6并配置了现代Linux系统,OS X 10.4或更高版本以及Windows Vista的操作系统上,如果访问本地服务器,某些浏览器可能会非常慢.原因是有时"localhost"被配置为在ipv4和ipv6 socktes上都可用,并且一些浏览器将首先尝试访问ipv6然后尝试访问ivp4.

所以解决方法是通过从我的hosts文件中注释掉以下行来禁用localhost中的ipv6:

::1             localhost 
Run Code Online (Sandbox Code Playgroud)

一旦我这样做,延迟问题就会消失.

我正在挖掘Flask,我很高兴这不是框架的问题.我知道它不可能.

  • 我发现这些很有用: Windows http://www.techunboxed.com/2012/08/how-to-disable-ipv6-in-windows-8.html Ubuntu http://www.noobslab.com/2012/05/ disable-ipv6-if-your-internet-is.html (2认同)

小智 79

将"threaded = True"添加为app.run()的参数,如下所示:http://arusahni.net/blog/2013/10/flask-multithreading.html

例如: app.run(host="0.0.0.0", port=8080, threaded=True)

ipv6禁用解决方案对我不起作用,但确实如此.

  • 对于那些通过启用线程"修复"它的人,请注意!在这种情况下,延迟是由于先前的请求没有正确关闭引起的,所以现在它实际上是[只堆叠很多线程](http://i.stack.imgur.com/lRUpS.png). (6认同)
  • 使用`Flask-Script`将`--threaded`传递给我的`manage.py`也可以. (5认同)

mik*_*eho 11

来自@ sajid-siddiqi的解决方案在技术上是正确的,但请记住Werkzeug中的内置WSGI服务器(它包装在Flask中以及它用于什么).app.run()

安装WSGI服务器以便能够处理多线程行为.我对各种WSGI服务器性能进行了大量研究.您的需求可能会有所不同,但如果您使用的只是Flask,那么我会推荐以下网络服务器之一.

对于Python 2.x:gevent

您可以使用命令通过pip安装gevent.有关如何相应修改代码的说明,请访问:http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#geventpip install gevent

对于Python 3.x:meinheld

gevent是更好的,但它仍然没有更新为使用python3(请参阅此线程的更新:https://github.com/gevent/gevent/issues/38).从我所看到的涉及实际测试的所有基准测试来看,meinheld似乎是最直接,最简单的WSGI服务器.(如果您不介意更多配置,也可以查看uWSGI.)

您也可以使用命令通过pip3安装meinheld.从那里,查看meinheld源中提供的示例以集成Flask:https://github.com/mopemope/meinheld/blob/master/example/flask_sample.pypip3 install meinheld

*注意:从我使用PyCharm开始,该行from meinheld import server突出显示为错误,但服务器将运行,因此您可以忽略该错误.


小智 11

而不是调用http://localhost:port/endpointcall http://127.0.0.1:port/endpoint。这为我消除了最初的 500 毫秒延迟。

  • 对我来说,它删除了大约 3 秒的时间(我从 0.0.0.0 移动到 127.0.0.1)。有人可以解释它为什么以及如何工作吗? (2认同)
  • 为什么以上帝的名义这会起作用?从 2.06 秒缩短到 0.002 秒。浏览器可以毫无问题地使用 localhost,但 localhost 上的 requests.get 需要 2 秒才能解析。 (2认同)

小智 6

threaded=True对我有用,但最后我发现这个问题是由于 Firefox 上的 Foxyproxy 造成的。因为当 Flask 应用程序在本地主机上运行时,如果

  • Foxyproxy 在 Firefox 上启用

缓慢的响应不会发生如果

  • Foxyproxy 在 Firefox 上被禁用

  • 使用其他浏览器访问网站

我发现的唯一解决方案是禁用 Foxyproxy,尝试将 localhost 添加到代理黑名单并调整设置,但它们都不起作用。


Ali*_*zan 6

我使用 Miheko 的回复来解决我的问题。

::1 localhost已在我的主机文件中注释掉,并且设置Threaded=true对我不起作用。每个 REST 请求都需要 1 秒来处理,而不是即时处理。

我正在使用 python 3.6,并且通过让 Flask 使用 gevent 作为其 WSGI,使 Flask 能够快速响应 REST 请求。

要使用 gevent,请安装它pip install gevent

之后,我使用https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41将flask设置为使用gevent。

如果链接断开,以下是脚本的重要部分:

from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey

# need to patch sockets to make requests async
# you may also need to call this before importing other packages that setup ssl
monkey.patch_all()

app = Flask(__name__) 


# define some REST endpoints... 

def main():

    # use gevent WSGI server instead of the Flask
    # instead of 5000, you can define whatever port you want.
    http = WSGIServer(('', 5000), app.wsgi_app) 

    # Serve your application
    http.serve_forever()


if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)


小智 5

我没有评论的声誉,所以我将其添加为"解决方案".我的问题是通过"threaded = True"来解决的,但是我想给出一些背景来区分我的问题和其他可能没有这个问题的问题.

  1. 我的问题只出现在使用python3运行Flask时.切换到python2,我不再有这个问题.
  2. 我的问题只有在使用Chrome访问api时才会显现,此时Chrome会显示预期的屏幕,但其他所有内容都会挂起(curl,ffx等),直到我重新加载或关闭Chrome标签,此时等待的所有其他内容周围返回了一个结果.

我最好的猜测是Chrome试图让会话保持打开状态,而Flask阻止后续请求.只要Chrome停止或重置连接,就会处理其他所有内容.

就我而言,线程修复了它.当然,我现在正在浏览其他人提供的一些链接,以确保它不会导致任何其他问题.