jjzjj

Flask keep-alive

BoatingTao 2023-11-10 原文

http 长连接

http/1.0默认不开启 connection:keep-alive
http/1.1默认开启

笔者想抓包测试一下http 1.1里面的长连接
一个简单的flask接口

# Flask==1.1.2
# Werkzeug==1.0.1

from flask import Flask, make_response
app = Flask(__name__)

@app.route('/hello', methods=['get'])
def hello():
    res = make_response('hello world!')
    return res

if __name__ == '__main__':
    app.run(host='127.0.0.1', debug=True, port=5001)

postman发送请求,wireshark抓包(过滤条件: ip.addr==127.0.0.1 and tcp.port==5001)
下图首两行可以看到TCP协议,标志位SYN,握手报文。(深灰色)
倒数四行TCP协议,标志位FIN, 是挥手报文。(深灰色)
图里剩下的内容应用层http协议,这就是我们发送、响应的报文。(绿色)
即一次http请求、响应需要tcp完整握手与挥手,再发起一次http请求也是同样效果。

image.png

response header


image.png

响应的HTTP协议版本为1.0 ,默认不开启keep-alive


image.png
# 增加 Connection=keep-alive
res.headers['Connection'] = 'keep-alive'

重启flask服务,再次抓包。可以看到 TCP Keep-Alive网络包


image.png

response header, keep-alive


image.png

此时http请求完成后,并未关闭TCP,再次用postman请求会发现并未出现握手。


image.png

这个http长连接笔者等待了10分钟也还是keep-alive的状态...emmmm
当然,关闭postman或者后端服务后肯定断开了。

笔者重新安装了一个flask最新版测试

flask==2.1.3 再次测试

# Flask==2.1.3
# Werkzeug==2.1.2
from flask import Flask, make_response

app = Flask(__name__)


@app.route('/hello', methods=['get', 'post'])
def hello():
    res = make_response('hello world')
    return res


if '__main__' == __name__:
    app.debug = True
    app.run(host='0.0.0.0', port=5000)

同样用postman发送请求,发现握手与挥手的报文


image.png

response header中connection为 close


image.png
# 代码中加入Connection
res.headers['Connection'] = 'keep-alive'

postman测试,发现tcp还是挥手了。


image.png

response header中居然有两个connection!


image.png
image.png

笔者以为是没设置对,尝试了其他方式仍然不得行!后发现是WerkZeug里面就是设置的 close

    #res.headers['Connection'] = 'keep-alive'
    #res.headers.setdefault('Connection', 'keep-alive')
    #res.headers.set('Connection', 'keep-alive')

WerkZeug包里面的serving文件

image.png

直接把源码改为Keep-Alive,果然就不会断开TCP了。

笔者查看了WerkZeug的更新记录,找到了日志说明。


image.png

image.png

由于WerkZeug使用的http服务是http.server这个python内置的http服务器,这里面的代码对http请求处理上存在问题导致的。
笔者终于找到原因了。(●ˇ∀ˇ●)

当然生产环境我们使用的WSGI HttpServer一般都会选择gunicorn或者uwsgi。不会使用WerkZeug。

有关Flask keep-alive的更多相关文章

  1. ruby - 具有 HTTPS、SSL 客户端证书和 Keep-Alive 支持的 Ruby HTTP 库? - 2

    我正在尝试用Ruby编写一个HTTPS客户端。它将使用HTTPS连接到服务器,传递身份验证token(通过单独的登录过程获得)和SSL客户端证书。我正在使用rest-client执行以下操作:client=RestClient::Resource.new(url,:ssl_client_cert=>OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),:ssl_client_key=>OpenSSL::PKey::RSA.new(File.read('./certificate/client

  2. javascript - HTTP 的 keep-alive 如何在 AJAX 应用程序中发挥作用 - 2

    HTTP中的“keep-alive”。有人说应该用好,但我无法得出任何结论。因此,请提供您的意见/答案/观点,以便我为此找到一些依据,它有什么作用?应该和不应该做的场景?它如何使AJAX应用程序变得更好?如果有风险,做和不做?感谢大家的投入。 最佳答案 首先,如果您与服务器的连接使用的是HTTP/1.1,那么您很可能已经在使用“keep-alive”。这是什么?从逻辑上讲,HTTP是一种无连接协议(protocol)。也就是说,对服务器的每个请求/响应都会创建一个新连接,执行其业务并断开连接。然而,在HTTP/1.1中,默认行为是保

  3. go - Keep-alive:死亡节点检测 - 2

    我在macOS本地主机上运行用Go(1.12)编写的客户端和套接字服务器。服务器在net.TCPConn上设置SetKeepAlive和SetKeepAlivePeriod。客户端发送数据包然后关闭连接(FIN)或客户端突然终止。Tcpdump显示即使在客户端关闭连接后,服务器仍继续发送保持事件探测。它不应该检测到对等点“死了”并关闭连接吗?这个问题很笼统,如果我遗漏了一些基础知识,请随时澄清。packagemainimport("flag""fmt""net""os""time")funcmain(){varclientboolflag.BoolVar(&client,"client

  4. c++ - TCP Sockets什么时候需要Keep-alive? - 2

    据我所知,在TCP套接字上保持事件状态有助于了解套接字是否刚刚打开以及两个套接字之间的连接是否实际上处于事件状态。所以,我有几个关于Winsocks2中Keepalive用法的问题想咨询一下:当keep-alive选项检测到死套接字时会发生什么?如何在不实际使用的情况下检查连接是活的还是死的send和recv?如果我必须使用send和recv然后功能首先使用keep-alive有什么意义? 最佳答案 Whathappenswhenkeep-aliveoptiondetectsadeadsocket?连接被重置,任何读取或写入都会出现

  5. c++ - TabCtrl_InsertItem : do we need to keep memory of the text alive? - 2

    对于TabCtrl_InsertItem,我们需要保留pszTextmember指向有效内存还是操作系统会复制文本以便我们可以立即清除文本?TCITEMtcItem={TCIF_TEXT};CStringstrText;for(inti=0;i我们如何才能知道对于这个函数和future的其他函数哪个是正确的?我在MSDN中找不到它。 最佳答案 操作系统会将字符串复制到内部数据结构中。您不需要维护支持字符数组。您可以在函数调用完成后立即释放它。通常,任何接收字符串的WindowsAPI函数都是这种情况。没错,MSDN文档中没有明确说明

  6. web前端面试高频考点——Vue的高级特性(动态组件、异步加载、keep-alive、mixin、Vuex、Vue-Router) - 2

    系列文章目录内容参考链接Vue基本使用Vue的基本使用(一文掌握Vue最基础的知识点)Vue通信和高级特性Vue组件间的通信及高级特性(多种组件间的通信、自定义v-model、nextTick、插槽)Vue高级特性Vue的高级特性(动态组件、异步加载、keep-alive、mixin、Vuex、Vue-Router)Vue原理1Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)Vue原理2Vue原理(diff算法、模板编译、组件渲染和更新、JS实现路由)Vue面试题web前端面试高频考点——Vue面试题文章目录系列文章目录一、Vue高级特性1、动态组件2、

  7. c# - 重现 "A connection that was expected to be kept alive was closed by the server." - 2

    我们在winforms应用程序中使用WebClient、.NET3.5sp1。对于一些用户来说,这个结果在消息异常中:“基础连接已关闭:服务器关闭了预期保持事件状态的连接。”在网络上搜索了一下,建议“修复”以禁用httpkeepalive,我们对此并不真正感兴趣,有人认为它可能是.NET库中的错误,等等。错误消息表明它是一个keepaliv'edhttp连接,它以某种方式被服务器(或代理)关闭,而WebClient的底层未正确检测到它。我们正在考虑捕获这个特定案例,然后再次尝试该请求。但是我们无法重现此异常。所以。我们如何才能正确捕获产生上述错误消息的情况。catch(WebExcep

  8. php - 如何使用 php 覆盖 Apache keep-alive header ? - 2

    在我的httpd.conf中有:KeepAliveTimeout1我试图在单个php脚本(而不是整个服务器)中覆盖ApacheKeepAliveTimeout设置,所以我有一个php脚本:header("Keep-Alive:timeout=60,max=100");不过好像没什么区别。我仍然得到回应:Keep-Alive:timeout=1,max=50有什么解决办法吗? 最佳答案 你不能那样做。它在那里是有正当理由的。Apachev2.2CoreFeaturesKeepAliveTimeout指令Thenumberofsecon

  9. 用于 HTTP keep-alive 的 PHP Guzzle 客户端 - 2

    我正在尝试连接到保持连接事件并发送分块数据的API。我有一个使用fsockopen的解决方案,它写入和读取流并使用while(!$stream->eof())。我想知道是否可以使用Guzzle获得相同的结果?我看到了Async方法,但有人可以告诉我如何等待流吗? 最佳答案 Guzzle6+支持PRS-7,它将响应主体定义为流。您可以同步或异步请求数据,这无关紧要。设置streamoption也很重要为您的要求:$client=newClient(/*...*/);$response=$client->get('http://some

  10. php - fast-cgi 连接php-fpm 和nginx 是否是持久(keep-alive)连接? - 2

    我正在尝试编写一个服务器演示来连接php-fpm,但我不知道php-fpm和nginx通过fast-cgi之间的连接是否是持久(keep-alive)连接?每次http请求到nginx时,nginx会再次通过tcp3-WayHandshake连接php-fpm吗?或者nginx和php-fpm之间的连接是一个保持连接并且nginx尝试重用它? 最佳答案 PHP-FPM是fastCGI协议(protocol)的实现,因此它遵守所有fastCGI规范要求。一个这样的要求是在section3.5ofthespecification,特别是

随机推荐