HTTP连接管理的那些事儿

1. HTTP连接

HTTP连接实际上就是TCP连接和一些使用连接的规则。TCP为HTTP提供了一条可靠的比特传输管道。从TCP连接一端填入的字节会从另一端以原有的顺序、正确地传送出来。

E.g. http://blog.youkuaiyun.com/okingniko/article/details/50986039
1. 浏览器解析出主机名blog.youkuaiyun.com
2. 浏览器查询这个主机的IP地址(DNS) 101.200.96.31
3. 浏览器获得端口号(80)
4. 浏览器发起到101.200.96.31端口80的连接
5. 浏览器向服务器发送一条HTTP GET报文
6. 浏览器从服务器读取HTTP响应报文
7. 浏览器关闭连接

TCP连接通过4个值<源IP、源端口、目的IP、目的端口>来识别每一条连接。

2.以TCP套接字的角度看HTTP连接

TODO: 添加常见套接字API的说明
更详细的说明可参见 Unix网络编程:套接字编程

套接字角度

3. HTTP性能的优化

3.1 TCP性能的考虑

  • TCP连接建立握手
  • TCP慢启动拥塞控制
  • 数据聚集的Nagle算法
    • Nagle算法试图在发送一个分组之前,将大量的TCP数据绑定在一起,以提高网络效率。Nagle算法会引发几种HTTP性能问题,首先,小的HTTP报文可能无法填满一个分组,辣么就需要等待额外数据,其次,Nagle算法会阻止数据的发送,直到有确定分组抵达为止,但确定分组本身会被延迟确定算法延迟100~200毫秒。
    • 可以通过设置参数TCP_NODELAY禁用Nagle算法。
  • 用于捎带确定的TCP延迟确定算法
    • 为了有效利用网络,TCP将返回的确定信息与输出的数据分组结合在一起。为了增加确定报文找到同向传输报文的可能性,TCP协议栈实现了一种”延迟确认”算法。
    • 延迟确定算法会在一个特定的窗口时间(通常是100~200ms)内将输出确认存放在缓冲区中,以寻找能够捎带它的输出数据分组。如果在那个时间段内没有数据分组,就将确认信息放在单独的分组传送。
  • TIME_WAIT时延和端口耗尽

3.2 HTTP连接的处理

  • 串行事务的处理时延
  • 提高HTTP的连接性能
    • 并行连接
      通过多条TCP连接发起并发的HTTP请求
    • 持久连接
      重用TCP连接,以消除连接及关闭时延
    • 管道化连接
      通过共享的TCP连接发起并发的HTTP请求
    • 复用的连接
      交替传送请求和响应报文(试验阶段)

3.3 持久连接

  1. 在事务处理结束之后仍然保持在打开状态的TCP连接被称为持久连接。重用已对目标服务器打开的空闲持久连接,就可以避开缓慢的连接建立阶段。而且,已经打开的连接还可以避免慢启动的拥塞适应阶段,以便更快速地进行数据的传输。
  2. 持久连接与并行连接配合使用可能是最高效的方式。持久连接有两种类型:HTTP/1.0+的keep-alive连接,以及现代的HTTP/1.1的persistent连接。
keep-alive连接:
  1. 通过形如
    Connection : Keep-Alive
    Keep-Alive: max=5, timeout=120

来指定持久连接。上述例子还说明服务器最多还会为另外5个事务保持连接的打开状态,或者将打开状态保持到连接空闲了2分钟之后。
2. Keep-alive和(不理解Connection首部的)代理一起使用时,会引发请求被忽略的情况,所以现代的代理都不转发Connection首部和所有名字出现在Connection值中的首部。可通过插入Proxy-Connection来解决。

HTTP/1.1 持久连接:
  1. 与HTTP/1.0+的keep-alive连接不同,HTTP/1.1持久连接在默认情况下是激活的。若要在事务处理结束之后将连接关闭,HTTP/1.1应用程序必须向报文中显示添加一个Connection:close首部。
  2. 持久连接的限制和规则
    • 发送了Connection:close请求报文后,客户端就无法在那条连接上发送更多的请求了。
    • 只有当连接上所有的报文都有正确的、自定义报文长度时——也就是说,实体主体部分的长度都和响应的Content-Length一致,或者是用分块传输编码方式编码的——连接才能持久保持。
    • HTTP/1.1的代理必须能够分别管理与客户端和服务器的持久连接——每个持久连接都只适用于一跳传输。
    • HTTP/1.1的应用程序必须能够从异步的关闭中恢复回来。只要不存在可能会累积起来的副作用,客户端都应该重试这条请求。

3.4 管道化连接

HTTP/1.1允许在持久连接上可选的使用请求管道。在响应到达之前,可以将多条请求放入队列。

3.5 关闭连接的奥秘

  • TCP连接是双向的,TCP连接的每一端都有一个输入队列和一个输出队列,用于数据的读或写。放入一端输出队列中的队列最终会出现在另一端的输入队列中。
  • 套接字调用close()会将TCP连接的输入和输出信道都关闭了,这被称为完全关闭,而shutdown()可以单独关闭输入或输出信道,这叫做半关闭
  • 想要正常关闭连接的应用程序应该先关闭其输出信道,然后周期性的检查信道的状态(查找数据或流的末尾)。如果在一定的时间内对端没有关闭输入信道,应用程序可以强制关闭连接,以节省资源。

4. 参考资料

  1. HTTP权威指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值