一、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的更多相关文章

  1. http keep - alive 与 长连接

    http1.0 2.0 1.1区别 你可以把 WebSocket 看成是 HTTP 协议为了支持长连接所打的一个大补丁,它和 HTTP 有一些共性,是为了解决 HTTP 本身无法解决的某些问题而做出的 ...

  2. HTTP的长连接和短连接

        本文总结&分享网络编程中涉及的长连接.短连接概念.     关键字:Keep-Alive,并发连接数限制,TCP,HTTP 一.什么是长连接 HTTP1.1规定了默认保持长连接(HTT ...

  3. HTTP长连接短连接

    一.什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...

  4. HTTP协议中的长连接和短连接(keep-alive状态)

    什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待在同 ...

  5. HTTP实现长连接(TTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持Connection: keep-alive)

    HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接.如果客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web ...

  6. JAVA网络编程Socket常见问题 【长连接专题】

    一. 网络程序运行过程中的常见异常及处理 第1个异常是 java.net.BindException:Address already in use: JVM_Bind. 该异常发生在服务器端进行new ...

  7. 长连接 Socket.IO

    概念 说到长连接,对应的就是短连接了.下面先说明一下长连接和短连接的区别: 短连接与长连接 通俗来讲,浏览器和服务器每进行一次通信,就建立一次连接,任务结束就中断连接,即短连接.相反地,假如通信结束( ...

  8. HTTP长连接、短连接使用及测试

    概念 HTTP短连接(非持久连接)是指,客户端和服务端进行一次HTTP请求/响应之后,就关闭连接.所以,下一次的HTTP请求/响应操作就需要重新建立连接. HTTP长连接(持久连接)是指,客户端和服务 ...

  9. 【转】HTTP长连接与短连接(2)

    一.什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待 ...

  10. [转载] http长连接和短连接

    转载自http://blog.csdn.net/shine0181/article/details/7799754/ HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP ...

随机推荐

  1. [Swift]LeetCode891. 子序列宽度之和 | Sum of Subsequence Widths

    Given an array of integers A, consider all non-empty subsequences of A. For any sequence S, let the  ...

  2. springboot 实战之一站式开发体验

    都说springboot是新形势的主流框架工具,然而我的工作中并没有真正用到springboot: 都说springboot里面并没有什么新技术,不过是组合了现有的组件而已,但是自己却说不出来: 都说 ...

  3. Jmeter-阶梯场景设置

    接上一篇[Jmeter-常用线程组设置及场景运行时间计算] Jmeter复杂场景设计,依赖插件jp@gc - Stepping Thread Group (deprecated)和jp@gc - Ul ...

  4. python网络-TFTP客户端开发(25)

    一. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议 特点: ...

  5. C# listview展示表格格式

    有时候我们需要展示表格格式的数据,首先想到的是用datagridview控件,比如更改datagridview某一行的数据,这样操作起来就比较麻烦,而listview属于轻量级,刷新和更改相对来说效率 ...

  6. java多线程(8)---阻塞队列

    阻塞队列 再写阻塞列队之前,我写了一篇有关queue集合相关博客,也主要是为这篇做铺垫的. 网址:[java提高]---queue集合  在这篇博客中我们接触的队列都是非阻塞队列,比如Priority ...

  7. SpringBoot入门教程(七)整合themeleaf+bootstrap

    Thymeleaf是用于Web和独立环境的现代服务器端Java模板引擎.Thymeleaf的主要目标是将优雅的自然模板带到您的开发工作流程中—HTML能够在浏览器中正确显示,并且可以作为静态原型,从而 ...

  8. 带着新人学springboot的应用10(springboot+定时任务+发邮件)

    接上一节,环境一样,这次来说另外两个任务,一个是定时任务,一个是发邮件. 1.定时任务 定时任务可以设置精确到秒的准确时间去自动执行方法. 我要一个程序每一秒钟说一句:java小新人最帅 于是,我就写 ...

  9. 行为驱动:Cucumber + Selenium + Java(二) - 第一个测试

    在上一篇中,我们搭建好了Selenium + Cucumber + Java的自动化测试环境,这一篇我们就赶紧开始编写我们的第一个BDD测试用例. 2.1 创建features 我们在新建的java项 ...

  10. Chapter 5 Blood Type——7

    "You say that a lot," I noted, trying to ignore the sudden trembling in my stomach and kee ...