一. HTTP事务时延原因(HTTP权威指南 P86)

1.客户端首先需要根据URI确定WEB服务器的IP和端口号, 那么DNS解析上花的时间会很多(大多数HTTP客户端会有一个小的DNS缓存)
 
2. 客户端会向服务器发送建立TCP连接请求, 每个请求建立会耗时间, 如果HTTP事务多的话, 这个时间会明显提高
 
3. 一旦连接建立, 客户端会通过此TCP管道来发送HTTP报文, 服务端会接收并读取处理, 这些都会消耗时间
 
4. WEB服务器会回送HTTP响应, 这也需要时间
 
这些TCP网络延迟的大小取决于硬件速度, 网络和服务器负载, 请求和响应报文的尺寸, 客户端和服务器之间的距离, TCP协议的技术复杂度也会对时延有巨大的影响
 
二. 性能聚焦区域
1. TCP连接的握手时延:
TCP连接握手步骤:    
a. 请求新的TCP连接时, 客户端需要向服务器发送一个小的TCP分组(通常是40-60字节), 这个分组设置了一个特殊的SYN标记. 说明这是一个连接请求
b. 如果服务器接受了连接, 就会对一些连接参数进行计算, 并向客户端回送一个TCP分组, 这个分组的SYN和ACK标记都被置位, 说明连接请求已被建立
c. 最后, 客户端向服务器会送一条确认信息, 通知它连接已成功建立, 现代的TCP栈都允许客户端在这个确认分组中发送数据
 
结论是: 小的HTTP事务可能会在TCP建立上花费50%, 或更多的时间, HTTP可以通过重用现存连接减少建立连接的时间
 
2. 延迟确认
a.由于因特网自身无法确保可靠的分组传输, TCP实现了自己的确认机制来确保数据的成功传输
 
每一个TCP段都会有一个序列号和数据完整性校验和, 每个段的接受者收到完好的信息时, 会想发送者回送小的确认分组, 如果发送者没有在指定的窗口时间收到确认信息, 发送者就认为这个分组已被破坏, 并重发数据
 

由于确认报文很小, 所以TCP允许再发往相同方向的输出数据分组中对其进行捎带. TCP将返回的确认信息与输出的数据分组结合在一起, 可以更有效的利用网络. 为了增加确认报文找到同向传输数据分组的可能性, 很多TCP栈都实现了"延迟确认"算法. 延迟确认算法会在一个特定的窗口时间(100-200ms) 将确认信息放在缓冲区内, 以寻找能够捎带它的输出数据分组, 如果窗口时间内没有输出数据, 则独立发送.

 
但是, http具有双峰特征的请求, 应答行为降低了捎带信息的可能. 当希望有相反方向回传数据的时候, 没有那么多, 所以延迟确认算法会有相当大的延迟, 所以可以调整或禁止延迟确认算法
在对TCP栈进行参数修改前, 需要对此有清楚的认识. TCP的这些算法是为了防止设计欠佳的应用对因特网的破坏. 对TCP进行的修改, 需要确保应用程序不会引发这些算法要避免的问题
 
3. TCP慢启动
TCP数据传输性能还取决于TCP连接的使用期(age). TCP连接会随着时间的进行自我"调谐", 起初会限制连接的最大速度, 如果数据成功传输, 会随着时间的推移提高传输速度, 这种调谐成为TCP慢启动, 用于防止因特网的突然过载和拥塞
TCP的慢启动限制了一个TCP端点在任一时刻可以传输的分组数, 简单的说, 每成功接受一个分组, 发送端就有一个发送另外两个分组的权限. 如果某个http事务有大量的数据需要发送, 是不能一次发送所有分组数据的, 必须发送一个分组, 等待确认, 然后可以发送两个分组, 每个分组都必须被确认, 这样就可以发送四个分组. 以此类推, 这种方式被称为"打开拥塞窗口"
由于存在这种拥塞控制特性. 所以新连接的传输速度会比已经交换过一些数据的"已调谐"的连接慢一些, 由于已调谐的连接更快些, 所以HTTP中有一些可以重用现存连接的工具
 
4. Nagle算法和TCP_NODELAY
TCP有一个数据流接口, 应用程序可以通过它将任意尺寸的数据放入TCP栈--一次只放一个字节也是可以的! 但是每一个TCP段都至少装载了40个字节的标记和首部, 所以如果TCP发送了大量包含少量数据的分组, 网络的性能就会严重下降.
Nagle算法试图发送一个分组之前, 将大的TCP数据绑定在一起, 以提高网络效率. Nagle算法鼓励发送全尺寸的数据段.LAN上1500字节, 因特网为几百字节. 只有当所有分组都被确认之后, Nagel算法才允许发送非全尺寸的数据, 如果其他分组仍在传输过程中, 就将那部分数据缓存起来, 只有当挂起分组被确认, 或者缓存区中积累了足够发送一个全尺寸的分组数据时, 才将缓存发出去
 
Nagel算法会引起几个HTTP性能问题, 首先, 小的HTTP报文可能无法填满一个分组, 可能会因为等待那些永远不会到来的额外数据而产生时延. 其次, Nagel算法与延迟确认之间的交互存在问题--Nagle算法会阻止数据的发送, 直到有分组抵达为止, 但是分组自身确认时间100-200ms
 
HTTP程序常常会在自己的栈中设置参数 TCP_NODELAY 来禁用nagel算法, 但是要确保向TCP写入大块数据吗这样就不会产生一堆小分组了
 
5. TIME_WAIT累积和端口耗尽
这个问题值得关注, 当某个TCP端点关闭TCP连接时, 会在内存中维护一个小的控制块, 用来记录最近所关闭连接的IP地址和端口号, 这类信息只维护一段时间(大约两分钟), 以确保这段时间内不会创建具有相同地址和端口号的连接, 实际上, 这个算法可以防止两分钟内创建, 关闭并重新创建两个具有相同IP地址和端口号的连接
2ML的连接关闭延迟通常不是什么问题, 但是性能基准环境下就可能会成为一个问题, 进行性能基准测试时, 通常只有一台或几台用来产生流量的计算机连接到某系统中去, 这样就限制了连接到服务器的客户端IP地址数, 而且, 服务器通常会在HTTP默认TCP端口80上进行监听, 用TIME_WAIT防止端口号重用时, 这些情况也限制了可用的连接值组合,
只有一个客户端和一台服务器的异常情况下, 构建一条TCP连接的4个值, 其中3个都是固定的, 只有源端口号可以随意改变. 每次客户端连接到服务器上去时, 都会获得新的源端口, 但由于源端口可用数量有限, 即使没有遇到端口耗尽问题, 也要特别注意大量处理打开状态的情况

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

  1. TCP的运输连接管理

    TCP的运输连接管理 TCP是面向连接的协议,有三个阶段:连接建立.数据传送 和 连接释放.运输连接的管理就是使运输连接的简历和释放都能正常地进行. 在TCP连接建立过程中要解决一下三个问题: 1.  ...

  2. TCP拥塞控制及连接管理

    在阅读此篇之前,博主强烈建议先看看TCP可靠传输及流量控制. 一.TCP拥塞控制 在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生拥塞(congestion ...

  3. TCP系列07—连接管理—6、TCP连接管理的状态机

            经过前面对TCP连接管理的介绍,我们本小节通过TCP连接管理的状态机来总结一下看看TCP连接的状态变化 一.TCP状态机整体状态转换图(截取自第二版TCPIP详解) 二.TCP连接建立 ...

  4. TCP系列02—连接管理—1、三次握手与四次挥手

    一.TCP连接管理概述 正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理. 通常一次完整的TCP数据传输一般包 ...

  5. TCP系列04—连接管理—3、TCP连接的半打开和半关闭

    在前面部分我们我们分别介绍了三次握手.四次挥手.同时打开和同时关闭,TCP连接还有两种场景分别是半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Du ...

  6. TCP系列03—连接管理—2、TCP连接的同时打开和同时关闭

    在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式.但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程 ...

  7. TCP系列08—连接管理—7、TCP 常见选项(option)

    一.TCP选项概述 在前面介绍TCP头的时候,我们说过tcp基本头下面可以带有tcp选项,其中有些选项只能在连接过程中随着SYN包发送,有些可以延后.下表汇总了一些tcp选项 其中我标记为红色的部分是 ...

  8. TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接

    一.TCP连接的ISN         之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...

  9. [TCP/IP] TCP的传输连接管理

    1.连接建立=>数据传输=>连接释放 2.主动发起连接的是客户端,被动接受连接的是服务器 3.三次握手 客户端 ==> SYN是1同步 ,ACK确认标志是0,seq序号是x ==&g ...

  10. TCP系列09—连接管理—8、TCP Reset

    我们在介绍TCP头的时候,提到过其中有个RST标志位.当一个TCP报文中这个标志位打开的时候,我们叫做reset包(严格的说应该叫做reset段,但是很多时候段包帧并不加以区分)或者简单称呼为rese ...

随机推荐

  1. 从jar中读取资源文件的问题

    在项目中遇到了一个问题,在IDE中读取配置文件的程序,打成架包以后,放到服务器上跑,报找不到资源文件的错误. 其中,资源文件的路径如下: 获取配置文件路径和读取的方法如下: private stati ...

  2. 管理SQL Server监控

    http://blog.csdn.net/DBA_Huangzj/article/category/1133081 http://www.cnblogs.com/bhtfg538/archive/20 ...

  3. Unity -- Collider(碰撞器与触发器)

    (2d与3d的Collider可以相互存在,但是无法相互协作,如2d是无法检测3d的,反之,一样) 在目前掌握的情况分析,在Unity中参与碰撞的物体分2大块:1.发起碰撞的物体.2.接收碰撞的物体. ...

  4. 进程间通信IPC、LPC、RPC

    进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法.进程是计算机系统分配资源的最小单位.每个进程都有自己的一部分独立的系 ...

  5. 终极报错解决方案:Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger failed with

    遇到这个报错的时候,不要慌 Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger fail ...

  6. mac mysql忘记密码解决办法

    http://www.jb51.net/article/87580.htm http://blog.csdn.net/soft2buy/article/details/50223373

  7. mac下mysqldump找不到命令

    之所以会出现MySQL或者mysqldump这样的命令找不到, 我们可以打开/usr/bin文件夹,发现bin目录中并没有mysql打头的UEF文件, 而在/usr/local/mysql/bin中可 ...

  8. jquery的ajax的success和fail用法

    $.ajax({ type:"POST", url: url, contentType: 'application/json;charset=utf-8', data: JSON. ...

  9. repeated-substring-pattern

    https://leetcode.com/problems/repeated-substring-pattern/ 下面这个方法,开始我觉得挺好.可惜还是超时了.后来我就加了一个剪枝策略,只有长度能够 ...

  10. django 实现下载功能

    from django.http import FileResponse def download(request): if..... file=open([path],'rb') response= ...