HTTP长连接--Keep-Alive
一、HTTP/1.0
HTTP1.0版本的Keep-alive并不像HTTP1.1那样是默认发送的,所以要想连接得到保持,必须手动配置发送connection:keep-alive字段。若想断开keep-alive连接,需发送Connection:close字段
注意:这里的连接是HTTP依赖的传输协议TCP,而不是HTTP本身。
为什么需要长连接?
长连接可以提高连接的利用效率,即HTTP可以复用一条连接。例如某个用户浏览一个网站,他很长一段时间才跳转到另一个链接,似乎保持长连接没有什么好处,很浪费资源。
但如果这个网站的并发量很大,保持长连接的好处就凸显了。如果每个请求都需要建立新的TCP连接,那对服务器的开销是相当的。
建立连接报文首部格式:
Connection:Keep-Alive
Keep-Alive:timeout ; max #参数之间用;分号隔开
参数:max 最大处理事务数量
timeout 连接保持的时间,单位为秒
断开连接报文首部格式:
Connection:close
Keep-Alive的建立过程
客户端向服务器在发送请求报文同时在首部添加发送Connection字段》服务器收到请求并处理connection字段》服务器回送Connection:Keep-Alive字段给客户端》客户端接收到connection字段》Keep-Alive连接建立成功
服务端自动断开过程:
客户端向服务器只是发送内容报文(不包含Connection字段)》服务器收到请求并处理》服务器返回客户端请求的资源并关闭连接》客户端接收资源,发现没有Connection字段,断开连接
客户端请求断开连接过程:
客户端向服务器发送Connection:close字段》服务器收到请求并处理connection字段》服务器回送响应资源并断开连接》客户端接收资源并断开连接
事务:
在基于TCP连接的http协议中,一个事务表示客户端向服务端请求一个资源并得到响应返回的过程。这个资源可能是html,css,js文件。
例如:

表示连接的最大处理事务数是5,连接时间是2分钟
Keep-Alive的限制和规则
(1)事务处理的接收端必须接收到发送端发送的正确的Content-Length字段,或者接收到MIME多部件多媒体类型(允许连接多次发送不同类型的资源)字段,或者接收到Chunked分块模式字段。以客户端向服务端发送资源为例(实际上,在一条HTTP信道上,数据传输是双向的,这里只是其中一种情形来讲述)。在一个非Keep—Alive的连接中,每一次资源请求都需要创建一个HTTP连接,出错了重传不会担心前后两次的Content-Length不相同问题。而如果是在Keep-Alive连接中,问题就没有那么简单了。想象一下出错客户端需要重新发送资源给服务端,而此时服务端端保存的可能还是上一条错误报文的Content-Length(可能是0),那么在接收新资源时候就会出现实体内容长度和content-length不一致等问题(这里存在了太多的细节问题)。
(2)不应该与无法确定是否支持Connection首部的代理服务器建立keep-alive连接,以防止出现下面要介绍的哑代理问题。但实际应用中,这一点不是总是能做到。
哑代理问题
盲中继指的是一些自身没有处理Connection:Keep-Alive的能力代理服务器。当客户端向服务端发送Connection字段的时候,通过代理服务器,而代理服务器没有处理Connection字段,而只将其当一个扩展首部来处理,将报文原原本本发送给服务端,服务端接收到Connecton字段后回送Connection字段。这时代理服务器还是原封不动将报文转送给客户端。此时客户端和服务器都建立了Keep-Alive连接,而代理服务器却毫不知情。它一直在等待客户端给它发送断开连接的字段,因为一个事务已经完成,已经没有必要保持连接了。这是建立了Keep-Alive连接客户端继续互相发送数据,而代理服务器收到的不是Connection:close字段,所以对此就会视而不见,就像‘盲’了一样。
根据《HTTP权威指南》中的描述,目前浏览器解决哑代理问题的一个解决方案使扩展首部字段Proxy-Connection,是由Netscape提出的。大致的实现原理是,客户端服务器会向代理服务器发送Proxy-Connection字段,如果对方是聪明的代理,它就会用Connection代替Proxy-Connection字段,发送给服务端,服务端接受到Connection字段之后就知道是要建立持久连接,这样客户端,代理,服务端三者都会明白需要建立一个持久连接。而如果对方是一个盲中继,它就会直接把Proxy-Connection当做扩展首部直接转发给服务端,服务端接收到后发现是Proxy-Connection字段,会自动忽略,也就是说不会建立持久连接,通常接下来事务完成之后就是直接关闭连接了。这样就不会产生上文所述的问题。
由于本人对这方面知识还接触比较少,在这里就不对Proxy-Connection作更深入阐述了。
二、HTTP/1.1
客户端(浏览器)如果使用的是HTTP/1.1版本,默认会发送connection:keep alive字段
,如果没有特殊说明,TCP连接是默认保持的,而需要将一个连接关闭,则需要客户端发送Connection:close首部字段。
HTTP1.1经过版本的更迭,HTTP1.1逐渐停止了对Keep-alive连接的支持,用一种名为持久连接(persistent connection)的改进型机制设计取代了它。这种机制默认连接建立之后是持久的,也就是说客户端不需要依靠首部添加Keep-alive字段来保持连接。在希望断开连接的时候,则需要客户端首部添加Connection:close字段。
持久连接的限制和规则:
(1)HTTP/1.1对代理服务器的要求更高,它必须能管理与客户端和服务端之间的持久连接。
(2)由于HTTP/1.1设备随时可能断开连接(因为出错;或者是连接空闲一段时间后,服务端做了逻辑处理,主动关闭;也可能是其他原因),客户端可能在没有接收到整条完整的响应,服务端就断开了连接。所以客户随时要做好重新发送请求的准备。
(3)一个用户客户端对任何服务器或者代理最多只能维持两条持久连接,以防止服务器过载。所以作为中间者身份的代理服务器可能需要更多到服务器的连接来支持并发的用户请求。例如有N个用户请求不同的服务器,代理需要维护2N条到任意服务器或者父代理的连接。
管道化连接
HTTP/1.1允许在持久连接的基础上自由选择使用请求管道。管道的原理很像队列。在响应到达前,客户端发送的请求可以放进管道里面,当第一条请求发送到服务端而还客户端还没有接收到响应的时候,后面的请求可以接着发送了。为什么可以这样?这就是管道的作用了,因为管道中的请求是‘提前准备好的’,它无需等待客户端判断已经接收到响应了再发送新的请求(这是非管道连接的串行请求)。在高时延的网络中,管道化连接有利于降低网络的环回时间,提高网络传输性能。
虽然管道化连接有它强大的优势,但是管道化连接也有它的局限性。
1)客户端的请求在管道中是有一定次序的。但由于HTTP报文是没有顺序,响应报文一旦次序出错,就无法与请求一一对应匹配起来。
2)一般来说,非幂等性(例如POST请求,下文会讲述)请求是不希望放进管道的。原因是,管道传输中如果出现了错误,请求和响应的次序无法得到保障,在一些订单或者涉及资金的POST提交中,结果是灾难性的。
3)在管道传输过程中,服务器关闭了连接,这时有许多没有完成的请求事务,那么客户端和服务端采取什么机制来确认已经处理和没有处理的事务这一问题值得商榷。客户端可能必须重新发送请求连接并且重新发送所有的管道中的请求。
三、重试和幂等性
当事务因为一条持续的连接的意外关闭而被终端,客户端需要重新发送请求。这种重试在管道化连接中更复杂。
一次HTTP请求的类型可能是GET , POST , HEAD , PUT , DELETE , TRACE , OPTION,如果重试前后对服务端的数据没有很大影响的请求类型就是幂等性的。显然,POST是非幂等的。关于幂等性的更多讨论,可以看看这篇文章:https://www.jianshu.com/p/178da1e2903c
四、最后,关于连接的关闭:
什么时候控制性地关闭连接,以及如何关闭连接,以达到信道上最高效率的数据传输是一个值得研究和讨论的问题。《HTTP权威指南》中也没有提供一些可行的方案。以后有接触到相关知识,我会继续补充。
参考文章:https://www.jianshu.com/p/178da1e2903c
HTTP长连接--Keep-Alive的更多相关文章
- http keep - alive 与 长连接
http1.0 2.0 1.1区别 你可以把 WebSocket 看成是 HTTP 协议为了支持长连接所打的一个大补丁,它和 HTTP 有一些共性,是为了解决 HTTP 本身无法解决的某些问题而做出的 ...
- HTTP的长连接和短连接
本文总结&分享网络编程中涉及的长连接.短连接概念. 关键字:Keep-Alive,并发连接数限制,TCP,HTTP 一.什么是长连接 HTTP1.1规定了默认保持长连接(HTT ...
- HTTP长连接短连接
一.什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...
- HTTP协议中的长连接和短连接(keep-alive状态)
什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待在同 ...
- HTTP实现长连接(TTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持Connection: keep-alive)
HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接.如果客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web ...
- JAVA网络编程Socket常见问题 【长连接专题】
一. 网络程序运行过程中的常见异常及处理 第1个异常是 java.net.BindException:Address already in use: JVM_Bind. 该异常发生在服务器端进行new ...
- 长连接 Socket.IO
概念 说到长连接,对应的就是短连接了.下面先说明一下长连接和短连接的区别: 短连接与长连接 通俗来讲,浏览器和服务器每进行一次通信,就建立一次连接,任务结束就中断连接,即短连接.相反地,假如通信结束( ...
- HTTP长连接、短连接使用及测试
概念 HTTP短连接(非持久连接)是指,客户端和服务端进行一次HTTP请求/响应之后,就关闭连接.所以,下一次的HTTP请求/响应操作就需要重新建立连接. HTTP长连接(持久连接)是指,客户端和服务 ...
- 【转】HTTP长连接与短连接(2)
一.什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...
- [转载] http长连接和短连接
转载自http://blog.csdn.net/shine0181/article/details/7799754/ HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP ...
随机推荐
- Python学习笔记【Nginx】:Nginx使用与完全卸载
安装与启动nginx 第一步:通过指令安装包 sudo apt install nginx sudo apt install nginx 第二步:安装成功后查看相关配置文件 ls /etc/n ...
- [Swift]LeetCode221. 最大正方形 | Maximal Square
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and re ...
- shell 问题备忘
一 ls结果赋给变量 dirSrc=$(ls test/ -l | awk '/^d/{print $NF}') echo "dirSrc is $dirSrc" 二 使用cut查 ...
- python网络-Socket之udp编程(24)
一.udp简介 udp --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议. udp不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地. udp在 ...
- java多线程(3)---synchronized、Lock
synchronized.Lock 一.概述 1.出现线程不安全的原因是什么? 如果我们创建的多个线程,存在着共享数据,那么就有可能出现线程的安全问题:当其中一个线程操作共享数据时,还未操作完成,另外 ...
- Spring中bean实例化的三种方式
之前我已经有好几篇博客介绍Spring框架了,不过当时我们都是使用注解来完成注入的,具体小伙伴可以参考这几篇博客(Spring&SpringMVC框架案例).那么今天我想来说说如何通过xml配 ...
- logback配置信息
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true&q ...
- 设计模式总结篇系列:抽象工厂模式(Abstract Factory)
在上一篇的工厂方法模式中,通过一个公用的类对其他具有相同特性(实现相同接口或继承同一父类)的类的对象进行创建.随之带来的问题在于:当新定义了一个具有相同特性的类时,需要修改工厂类.这与设计模式中的开闭 ...
- [十五]java.math包简介,RoundingMode与MathContext
java.math包提供了java中的数学类 包括基本的浮点库.复杂运算以及任意精度的数据运算 '可以看得到,主要包括三个类一个枚举 BigDecimal和BigInteger接下来会详细介绍 先 ...
- iOS 加锁的方式
iOS多线程编程中,经常碰到多个线程访问共同的一个资源,在线程相互交互的情况下,需要一些同步措施,来保证线程之间交互的时候是安全的.下面我们一起看一下学一下iOS的几种常用的加锁方式,希望对大家有所帮 ...