本文是《HTTP权威指南》读书笔记;

几乎所有的HTTP通信都是通过TCP/IP承载的,当HTTP要传送一些报文时,会以流的形式将报文数据的内容通过一条打开的TCP连接按序传输。因此HTTP连接实际上就是TCP连接和一些使用连接的规则。

1 Connection首部

HTTP允许在客户端与最终的源服务器中存在一串的HTTP实体(代理,网关,高速缓存等)。HTTP的Connection首部字段中有一个由逗号分隔的连接标签列表,这些标签为此连接指定了一些不会传播到其他连接中的选项。因此如果HTTP报文的连接标签中包含了HTTP首部字段的名称,则在将报文转发出去前,必须删除所有连接标签中出现的首部字段。

2.  HTTP优化连接的方法(除了串行连接)

2.1 并行连接

通过多条TCP连接发起并发的HTTP请求。HTTP允许客户端打开多条连接,并行地执行多个HTTP事务。但打开多条连接会消耗大量的内存资源 ,引发自身的性能问题,并且一个WEB页面可能存在数百个对象(事务),服务器要处理多个用户的连接请求,多条连接也会等造成服务器性能的下降。虽然并行连接看起来会快一些(多个对象同时在加载),但实际上由于网络带宽等的限制,速度也没什么提升,但基本上还是会比串行连接快。实际上,浏览器是使用了并行连接的,但会将连接的个数限制在一个较小的值(通常为4个),并且服务器可以随意关闭来自同一个客户端的超量连接。

2.2 持久连接

重用TCP连接,消除连接与关闭的时延。

Web客户端经常会打开到同一站点的连接(Web页面里的内容大部分是来自同一个Web服务器),因此初始了对某服务器的

HTTP请求的应用程序很可能在不久的将来发起对该服务器的更多请求 (如获取图片等),这种性质称为站点的本地性。因此HTTP /1.1(或HTTP/1.0的增强版本)允许HTTP设备在事务处理完毕后,将TCP连接保持在打开状态,以便为未来的HTTP请求重用现在的连接。我们将在事务处理完毕后仍保持TCP为打开状态的连接为持久连接,直到客户端或服务器决定将其关闭。非持久连接会在事务处理完毕后关闭连接。重用已对目标服务器打开的空闲持久连接,可以避免缓慢的连接建立过程,还可以避免慢启动的拥塞适应阶段,以便可以快速地传送数据。但持久连接的管理需要非常小心,否则可以会累积出大量的空闲持久连接,浪费客户端与服务器的资源。

现在的Web应用程序一般都会将持久连接与并行连接配合使用(打开少量的并行连接,其中的每一个都是持久连接),以充分利用这两者的优点.

持久连接可以节省建立连接需要的时延,串行连接与持久连接的时间耗费对比:

持久连接又分为两种:HTTP/1.0+“keep-alive”持久连接和HTTP/1.1的“persistent”连接。

2.2.1 HTTP/1.0+“keep-alive”持久连接

实现HTTP/1.0+“keep-alive”持久连接的客户端可以通过包含Connection:Keep-Alive首部将请求将连接保持在打开状态,如果服务器愿意为下一条请求将连接保持在打开状态,则在响应中包含相同的Connection首部,如果在响应报文里没有Connection:Keep-Alive首部,则客户端会认为服务器不支持keep-alive,则会在发回响应报文之后将连接关闭。客户端和

服务器可以在任意时刻关闭空闲的“keep-alive”持久连接,并可以随意限制keep-alive连接可以处理的事务的数量。并且客户端发送的希望保持持久连接的报文里一定需要含有Connection:Keep-Alive首部,否则服务器就会在没有这个首部的请求之后关闭这个持久连接。并且报文的主体部分必须的正确的Content-Length字段来说明主体的长度,否则就不能使用持久连接,因为没有这个字段,处理的那一端没有办法判断这条报文的结束和下一条报文的开始。代理和网关要执行Connection规则。

由于HTTP请求在到达目的服务器的中间可能会经过若干个代理或网关,这就可能存在不能理解Connection首部的代理,将整个报文不经过处理(需要将Connection首部中出现的字段删除,包括了Connection:Keep-Alive)就直接转发出去,这就会导致哑代理(客户端认为服务器支持Keep-Alive,服务器认为客户端请求:Keep-Alive,但实际上代理根本就识别Keep-Alive首部):

2.2.2 HTTP/1.1的“persistent”连接

HTTP/1.1的“persistent”连接在默认情况下是激活的,因此如果要关闭一条持久连接,需要在报文中显示在添加Connectin:close 首部,否则HTTP/1.1连接就仍将维持在打开状态,但服务器或客户端仍可随时关闭空闲的连接。

使用HTTP/1.1的持久连接需要遵循以下规则:

  • 实体主体部分的长度与Content-Length一致,或用分块传输编码方式编码;
  • 每个持久连接只适合一跳传输,也就是中间的代理与网关要能够分别管理客户端和服务器的持久连接;
  • 一个客户端最多可以与同一个服务器建立2条持久连接

2.3管道化连接

通过共享的TCP连接发起并发的HTTP请求;

HTTP/1.1的持久连接允许可选地使用请求管道。在响应到达之前,可以将多条请求放入队列,当第一条请求发送后,第二条,第三条请求也可以开始发送了:

使用管道连接需要遵循的规则:

若无法确定连接是持久的,就不能用管道;必须按照与请求相同的顺序回送HTTP响应,若响应失序,则会没有办法将请求与响应对应起来;客户端需要做好连接会在任意时刻关闭的准备;客户端不应该用管道发送一些会产生副作用的请求(POST)

2.4 复用的连接

交替传送请求与响应报文(实验阶段)

3 HTTP连接的关闭

TCP连接是双向的,每一端都会有一个输入与输出信道,应用程序可以关闭这两个信道的任意一个,通过套接字调用close()会关闭输入与输出信道,这叫完全关闭,调用shutdown()会关掉其中的一个,这称为半关闭。

使用半关闭时,关闭输出信道总是安全的,另一端会在其缓冲区中读完所有数据后收到一个通知,说明流结束了,它就可以知道连接关闭了。但关闭输入信道是比较危险的。如果另一端向已经关闭的输入信道发送数据,操作系统会向另一端的的机器发送一个TCP“连接被对端重置”的报文,大多数操作系统会认为这是一个严重的错误,会删除对端还未读取的所有的缓冲区里的数据,这对于管道化连接来说是致命的(许多还没有被读取的正确的响应数据都被清空了);

因此,应用程序在关闭连接时,应先关闭输出信道,然后等待另一端的实体关闭它的输出信道,之后就可以关闭输入信道了。

HTTP连接管理的更多相关文章

  1. 转-HttpClient4.3 连接管理

    转 http://www.yeetrack.com/?p=782 2.1.持久连接 两个主机建立连接的过程是很复杂的一个过程,涉及到多个数据包的交换,并且也很耗时间.Http连接需要的三次握手开销很大 ...

  2. 【转】Oracle RAC 环境下的连接管理

    文章转自:http://www.oracle.com/technetwork/cn/articles/database-performance/oracle-rac-connection-mgmt-1 ...

  3. HTTP(一) 连接管理

    ・HTTP是如何使用TCP连接的 HTTP传送一条报文时,以流的形式将报文数据内容通过一条打开的TCP连接按序传输. TCP收到数据流之后,由TCP/IP软件将数据流砍成被称作段的小数据块,并将段封装 ...

  4. 在SSIS 的 64 位版本中不支持 Excel 连接管理器

    Microsoft sql server 2008 R2——> SQL SERVER Business Intelligence Development Studio 使用EXCEL数据源或目标 ...

  5. 连接管理VMware SphereESXi

    连接管理VMware SphereESXi 1. 准备 下载VMware-viclient-all-5.5.0-1993072,并按照提示安装 2. 使用VMware Sphere Client链接事 ...

  6. 一个Socket连接管理池(心跳机制)

    一个Socket连接管理池(心跳机制) http://cuisuqiang.iteye.com/blog/1489661

  7. boost::asio 连接管理11 如何关闭连接

    在实际产品运行中,对连接管理有了更新的认识,这里分享一下. shared_ptr管理连接对象的生命周期 shared_ptr的引用计数器决定了连接对象的生命周期.这里我说的连接对象就是在我的前文:ht ...

  8. Openfire分析之三:ConnectionManager 连接管理(1)

    Openfire是怎么实现连接请求的? XMPPServer.start()方法,完成Openfire的启动.但是,XMPPServer.start()方法中,并没有提及如何监听端口,那么Openfi ...

  9. SOFA 源码分析 — 连接管理器

    前言 RPC 框架需要维护客户端和服务端的连接,通常是一个客户端对应多个服务端,而客户端看到的是接口,并不是服务端的地址,服务端地址对于客户端来讲是透明的. 那么,如何实现这样一个 RPC 框架的网络 ...

  10. Netty中的连接管理

    连接管理是我们首先需要关注的,检测空闲连接以及超时对于及时释放资源来说是至关重要的.由于这是一项常见的任务,Netty特地为它提供了几个ChannelHandler实现. 用于空闲连接以及超时的Cha ...

随机推荐

  1. Batis-iBatis基本操作(增删改查)

    Batis-iBatis基本操作(增删改查) 时间 2014-04-10 17:55:20  CSDN博客 原文  http://blog.csdn.net/mazhaojuan/article/de ...

  2. C++ "+="等运算符使用bug

    昨晚写了一个程序,使用了"+="运算符,结果总不是我想要的,查了一晚没找到,今早才发现: timeInterval = tpImP.staTime - imgPara[serial ...

  3. Ubuntu安装Hadoop与Spark

    更新apt 用 hadoop 用户登录后,我们先更新一下 apt,后续我们使用 apt 安装软件,如果没更新可能有一些软件安装不了.按 ctrl+alt+t 打开终端窗口,执行如下命令: sudo a ...

  4. IEEE 802.11p (WAVE,Wireless Access in the Vehicular Environment)

    IEEE 802.11p(又称WAVE,Wireless Access in the Vehicular Environment)是一个由IEEE 802.11标准扩充的通讯协定.这个通讯协定主要用在 ...

  5. MySQL练习题

    MySQL练习题 一.表关系 请创建如下表,并创建相关约束 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 3.查询平均成绩大于60分的同学的学号和平均成 ...

  6. rank()函数的使用

    排序: ---rank()over(order by 列名 排序)的结果是不连续的,如果有4个人,其中有3个是并列第1名,那么最后的排序结果结果如:1 1 1 4select scoreid, stu ...

  7. 动态生成二维码插件 jquery.qrcode.js

    前段时间做项目,需要动态生成一个二维码,于是就在网上找了一下发现一个jquery插件jquery.qrcode.js,所以今天就简单说一下这个插件的使用: jquery.qrcode.js是依赖jqu ...

  8. 查询SqlServer中每张表的记录数

    select schema_name(t.schema_id) as [ Schema ], t. name as TableName,i. rows as [RowCount] from sys.t ...

  9. BZOJ 4726: [POI2017]Sabota?

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 301  Solved ...

  10. Python 【第五章】:线程、进程和协程

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...