- 问题陈述:* 在我尝试从Chrome浏览器访问不存在的文件后,Flask上的Web服务器无法处理HTTP请求。当Chrome关闭或访问确实存在的页面时,会立即处理积压的HTTP请求。
- 影响:* Web服务器可用性差。
- 问题:* 为什么会发生这种情况,如何在不以线程模式运行Flask的情况下修复它?
The closest post I found online is this: github.com/pallets/flask/issues/2188 but could not find exactly the same problem and solution. Looking forward to your thoughts - thanks so much for your help!
- 主要假设:* Chrome没有读取404响应的所有内容,Flask正在等待读取所有内容
- 详细数据:**
- 重现问题的步骤:*
1)运行最小 flask 应用程序(http://flask.pocoo.org/docs/0.12/quickstart/):
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
app.run()
- Running on хттп://127.0.0.1:5000/ (Press CTRL+C to quit)
2)验证您是否在浏览器或curl中得到"Hello world"响应:
curl-v本地主机:5000/
3)在Chrome浏览器中,转到localhost:5000/pagethatdoesnotexists,在浏览器中观察到"未找到"错误
4)重复curl-v本地主机:5000/命令
观察到连接已建立但未收到响应,例如:
curl-v localhost:5000/正在尝试::1 ... * 连接失败 * 连接到::1端口5000失败:连接被拒绝 * 正在尝试127.0.0.1 ... * 已连接到本地主机(127.0.0.1)端口5000(#0)
GET/HTTP/1.1主机:本地主机:5000用户代理: curl /7.49.0接受:/*
5)在Chrome浏览器中,转到存在的页面或关闭Chrome浏览器
观察对 curl 的即时响应:
- HTTP 1.0,假设在正文之后关闭〈HTTP/1.0 200 OK〈内容类型:文本/html;字符集= utf-8〈内容长度:13〈服务器:工具/0.11.10 Python/3.5.1〈日期:2017年2月28日星期二格林尼治标准时间21:44:20〈
- 正在关闭连接0 Hello,World!
可能需要多次尝试才能重现问题。通常10次中有8次以上发生
- 其他信息:**
1)我可以使用Safari或telnet或python脚本来代替curl-同样问题
2)Safari不会产生问题,而Chrome会
3)我试图通过发送与Chrome完全相同的http请求来模仿Chrome,但无法重现问题。Chrome可能会做其他事情。
4)当我在线程模式下运行Flask(用不同的线程处理每个请求)时,问题就消失了。
5)版本:
Chrome版本56.0.2924.87(64位)
Python 3.5.2语言|Anaconda 4.1.1(64位)|(默认值,2016年7月2日17:53:06)[愚者4.4.7 20120313(红帽4.4.7 - 1)]在Linux上运行
flask 版本'0.11.1'
6)AWS Ubuntu生产服务器计算机上也会出现此问题
7)尝试在404 http响应中发送自定义标题,但没有成功
@app.errorhandler(404)
def page_not_found(e):
# return render_template('404.html'), 404
resp = make_response(render_template('404.html'), 404)
# resp.headers['Connection'] = 'close'
resp.headers['Cache-Control'] = 'no-cache, no-store'
return resp
- 更新**
我能够重现这个问题,没有404错误,只是从Chrome的正常http请求。在Flask日志中没有观察到任何错误。
这里是video with the problem demonstration
另一个有趣的事情-如果在Chrome浏览器中使用隐姓埋名的窗口,这个问题是不会被观察到的。然而,在正常模式下清除缓存Chrome并不能解决这个问题。
2条答案
按热度按时间ktecyv1j1#
启用线程。
TL;DR
这个问题仍然存在。当页面预取被启用时,Chrome似乎没有关闭连接,它阻止了服务器的执行,从而阻止了后续请求的处理。
在我的情况下,问题甚至最糟糕,因为基于Android的手机也使用这种预取功能与相同的结果,我不能改变每个客户端的设置。
我的解决方案/变通方法是在底层
werkzeug
服务器(https://werkzeug.palletsprojects.com/en/0.16.x/serving/#werkzeug.serving.run_simple)中启用threading
选项。当然,这在服务器端会占用更多的资源,但它允许我们将行为不正常的请求/客户端分离到一个单独的线程中,而不会阻塞其他请求。我还检查了请求处理是否正确完成,至少在Flask端是这样的。所以问题一定是在Chrome /其他客户端或者底层的
werkzeug
服务器上。db2dz4w82#
同样的问题我已经遇到两次了。
相同的环境:纯Flask(无反向代理),最简单的应用程序。
在你用Chrome/Chromium打开URL后-- Flask将挂起,不会响应其他客户端(curl、postman、firefox、python-request等)。
Chrome的解决方法
在Chrome/Chromium中禁用URL预测服务(* 选项的实际名称见屏幕截图 *)
真实的溶液( flask )
即将到来-贡献是受欢迎的!(* 最有可能我永远不会解决这个 *)。