首页 > 其他分享 >关于HTTP Keep-Alive的大揭密

关于HTTP Keep-Alive的大揭密

时间:2023-04-20 12:33:00浏览次数:37  
标签:HTTP 请求 首部 Alive Keep Connection 连接 客户端

keep-Alive首部只是请求将连接保持在活跃状态。发出keep-alive请求之后,客户端和服务器并不一定会同意进行keep-alive会话。它们可以在任意时刻关闭空闲的keep-alive连接,并可随意限制keep-alive连接所处理事务的数量。

可以用Keep-Alive通用首部中指定的、由逗号分隔的选项来调节keep-alive的行为。

  • 参数timeout是在Keep-Alive响应首部发送的。它估计了服务器希望将连接保持在活跃状态的时间。这并不是一个承诺值。
  • 参数max是在Keep-Alive响应首部发送的。它估计了服务器还希望为多少个事务保持此连接的活跃状态。这并不是一个承诺值。
  • Keep-Alive首部还可支持任意未经处理的属性,这些属性主要用于诊断和调试。语法为name [=value]。

Keep-Alive首部完全是可选的,但只有在提供Connection:Keep-Alive时才能使用它

此外使用keep-alive连接时有一些限制和一些需要注意的地方。

  • 在HTTP/1.0中,keep-alive并不是默认使用的。客户端必须发送一个Connection: Keep-Alive请求首部来激活keep-alive连接。
  • Connection: Keep-Alive首部必须随所有希望保持持久连接的报文一起发送。如果客户端没有发送Connection:Keep-Alive首部,服务器就会在那条请求之后关闭连接。
  • 通过检测响应中是否包含Connection: Keep-Alive响应首部,客户端可以判断服务器是否会在发出响应之后关闭连接。
  • 只有在无需检测到连接的关闭即可确定报文实体主体部分长度的情况下,才能将连接保持在打开状态——也就是说实体的主体部分必须有正确的Content-Length,有多部件媒体类型,或者用分块传输编码的方式进行了编码。在一条keep-alive信道中回送错误的Content-Length是很糟糕的事,这样的话,事务处理的另一端就无法精确地检测出一条报文的结束和另一条报文的开始了。
  • 代理和网关必须执行Connection首部的规则。代理或网关必须在将报文转发出去或将其高速缓存之前,删除在Connection首部中命名的所有首部字段以及Connection首部自身。
  • 严格来说,不应该与无法确定是否支持Connection首部的代理服务器建立keep-alive连接,以防止出现下面要介绍的哑代理问题。在实际应用中不是总能做到这一点的。
  • 从技术上来讲,应该忽略所有来自HTTP/1.0设备的Connection首部字段(包括Connection: Keep-Alive),因为它们可能是由比较老的代理服务器误转发的。但实际上,尽管可能会有在老代理上挂起的危险,有些客户端和服务器还是会违反这条规则。
  • 除非重复发送请求会产生其他一些副作用,否则如果在客户端收到完整的响应之前连接就关闭了,客户端就一定要做好重试请求的准备。

HTTP/1.1逐渐停止了对keep-alive连接的支持,用一种名为持久连接(persistent connection)的改进型设计取代了它。持久连接的目的与keep-alive连接的目的相同,但工作机制更优一些。

与HTTP/1.0+的keep-alive连接不同,HTTP/1.1持久连接在默认情况下是激活的。除非特别指明,否则HTTP/1.1假定所有连接都是持久的。要在事务处理结束之后将连接关闭,HTTP/1.1应用程序必须向报文中显式地添加一个Connection:close首部。这是与以前的HTTP协议版本很重要的区别,在以前的版本中,keep-alive连接要么是可选的,要么根本就不支持。

HTTP/1.1客户端假定在收到响应后,除非响应中包含了Connection: close首部,不然HTTP/1.1连接就仍维持在打开状态。但是,客户端和服务器仍然可以随时关闭空闲的连接。不发送Connection: close并不意味着服务器承诺永远将连接保持在打开状态。

在持久连接的使用中有以下限制和需要注意的地方。

  • 发送了Connection: close请求首部之后,客户端就无法在那条连接上发送更多的请求了。
  • 如果客户端不想在连接上发送其他请求了,就应该在最后一条请求中发送一个Connection: close请求首部。
  • 只有当连接上所有的报文都有正确的、自定义报文长度时——也就是说,实体主体部分的长度都和相应的Content-Length一致,或者是用分块传输编码方式编码的——连接才能持久保持。
  • HTTP/1.1的代理必须能够分别管理与客户端和服务器的持久连接——每个持久连接都只适用于一跳传输。
  • (由于较老的代理会转发Connection首部,所以)HTTP/1.1的代理服务器不应该与HTTP/1.0客户端建立持久连接,除非它们了解客户端的处理能力。实际上,这一点是很难做到的,很多厂商都违背了这一原则。
  • 尽管服务器不应该试图在传输报文的过程中关闭连接,而且在关闭连接之前至少应该响应一条请求,但不管Connection首部取了什么值,HTTP/1.1设备都可以在任意时刻关闭连接。
  • HTTP/1.1应用程序必须能够从异步的关闭中恢复出来。只要不存在可能会累积起来的副作用,客户端都应该重试这条请求。
  • 除非重复发起请求会产生副作用,否则如果在客户端收到整条响应之前连接关闭了,客户端就必须要重新发起请求。
  • 一个用户客户端对任何服务器或代理最多只能维护两条持久连接,以防服务器过载。代理可能需要更多到服务器的连接来支持并发用户的通信,所以,如果有N个用户试图访问服务器的话,代理最多要维持2N条到任意服务器或父代理的连接。

HTTP/1.1允许在持久连接上可选地使用请求管道。这是相对于keep-alive连接的又一性能优化。在响应到达之前,可以将多条请求放入队列。当第一条请求通过网络流向地球另一端的服务器时,第二条和第三条请求也可以开始发送了。在高时延网络条件下,这样做可以降低网络的环回时间,提高性能。

对管道化连接有几条限制。

  • 如果HTTP客户端无法确认连接是持久的,就不应该使用管道。
  • 必须按照与请求相同的顺序回送HTTP响应。HTTP报文中没有序列号标签,因此如果收到的响应失序了,就没办法将其与请求匹配起来了。
  • HTTP客户端必须做好连接会在任意时刻关闭的准备,还要准备好重发所有未完成的管道化请求。如果客户端打开了一条持久连接,并立即发出了10条请求,服务器可能在只处理了,比方说,5条请求之后关闭连接。剩下的5条请求会失败,客户端必须能够应对这些过早关闭连接的情况,重新发出这些请求。
  • HTTP客户端不应该用管道化的方式发送会产生副作用的请求(比如POST)。总之,出错的时候,管道化方式会阻碍客户端了解服务器执行的是一系列管道化请求中的哪一些。由于无法安全地重试POST这样的非幂等请求,所以出错时,就存在某些方法永远不会被执行的风险。

标签:HTTP,请求,首部,Alive,Keep,Connection,连接,客户端
From: https://blog.51cto.com/key3feng/6209486

相关文章

  • 安装nginx-http-concat和nginx平滑升級
    评:Nginx_concat_module是淘宝开发的基于Nginx减少HTTP请求数量的扩展模块,主要是用于合并减少前端用户Request的HTTP请求的数量下载后把它放在/usr/local/src/文件夹中,到时候nginx需要指定该目录这个需要重新编译nginx,所以顺便把nginx升级了下。下载最新版本Linux代......
  • lvs+keepalived 实现负载均衡与高可用
    参考拓扑结构 1、在两台DirectorServer上安装lvs与keepalivedyum-yinstallkeepalivedipvsadm2、修改两台DirectorServer中/etc/keepalived/keepalived.conf配置文件 global_defs{notification_email{root@localhost#默认......
  • http 前端5种请求优化方法
    1、减少请求数量:可以通过将多个资源(例如JavaScript、CSS、图像等)合并为单个文件,从而减少HTTP请求的数量。另外,使用CDN(内容分发网络)也可以减少跨地                域的请求延迟。2、缓存请求结果:对于一些不会频繁更新的资源,可以将它......
  • fix Linux apt-get install package HTTPS error All In One
    fixLinuxapt-getinstallpackageHTTPSerrorAllInOneerrorsE:Themethoddriver/usr/libapt/methods/httpscouldnotbefound.N:Isthepackageapt-transport-httpsinstalled?solutionssymbollinksoftlink/软链接$cd/usr/lib/apt/methods#symbo......
  • chatgpt--http
    Java可以通过很多方式来实现http请求,其中比较常用的有以下几种方式:1.HttpURLConnection:Java提供的标准库中的一个类,可以轻松处理http请求和响应,支持GET、POST、PUT、DELETE等请求方式。以下是一个使用HttpURLConnection发送GET请求的示例代码:```javaURLurl=......
  • uhttp luci simple-app
    uhttplucisimple-appseehttps://forum.openwrt.org/t/rest-api-supported-in-openwrt/17210/6 YouprobablydowantLuci,oratleasttotakealookathowLucidoesit.POSTdataisinthebodyoftherequest.Lucicreatesa ltn12compatiblesourcetorea......
  • 注册中心对比: zookeeper&&etcd&&consul
    1.注册中心概念注册中心主要有三种角色:服务提供者(RPCServer):在启动时,向Registry注册自身服务,并向Registry定期发送心跳汇报存活状态。服务消费者(RPCClient):在启动时,向Registry订阅服务,把Registry返回的服务节点列表缓存在本地内存中,并与RPCSever建立连接。服务注册......
  • http模拟状态码
    引言HTTP状态码是客户端(浏览器)和服务器之间进行通信的基础。当浏览器请求网页时,服务器会返回一个状态码,告诉浏览器请求的网页是否成功、失败或有其他问题。在本文中,将讨论HTTP状态码及使用Nginx做代理模拟常见状态码。本文分为两部分HTTP状态码基础介绍HTTP状态码模拟实......
  • 12.深入理解 Http 协议
    深入理解Http协议一、Http协议入门1.1什么是http协议http协议:对浏览器客户端和服务器端之间数据传输的格式规范二、查看http协议的工具1)使用火狐的firebug插件(右键->firebug->网络)2)使用谷歌的“审查元素”2.1http协议内容请求(浏览器-》服务器)......
  • IDEA启动报错Internal error. Please refer to https://jb.gg/ide/critical-startup-e
    CMD右键以管理员身份运行netshwinsockreset完成后重启netshwinsockreset命令,作用是重置Winsock目录。如果一台机器上的Winsock协议配置有问题的话将会导致网络连接等问题,就需要用netshwinsockreset命令来重置Winsock目录借以恢复网络。......