高效管理http连接
1.Http连接基础
Http协议承载了互联网上的主要流量,然而说到传输,还要回归到最基本的网络分层模型TCP/IP。TCP/IP是全球计算机及网络设备都在使用的一种常用的分组交互网络分层协议集。客户端可以打开一条TCP/IP连接,与世界上的任何服务器进行数据交换,并且交换的数据永远不会丢失,受损或失序。
下面是常见的TCP/IP分层协议,分为安全与非安全版本。

由图可知,HTTP的整个传输过程可以描述为“HTTP over TCP over IP”。TCP是可靠地传输协议,就好像一条管道,从TCP连接一段填入的字节会从另外一端以原有的顺序,正确的传送出来。
TCP层与IP层都有自己的协议,他们对数据的关注点不同。总的来说,TCP段包含了目的端口与源端口,用来建立程序之间的连接。IP段包含了目的IP与源IP,用来进行网络寻址,最终建立机器之间的连接。而一条TCP连接正是根据这四点唯一对应的:
<源IP地址,源端口号,目的IP地址,目的端口号>
不同的连接不可以拥有完全相同的四个属性。对于一般功能而言,自己发起的连接中源端口号是随机生成的。
2.http连接性能
由于http数据是通过TCP传输的,http连接的性能很大程度上取决于TCP通道的性能。我们先分析一个正常的http事务。

- 客户端如果拿到的是域名,则需要先从DNS服务器中解析获得服务器IP地址,这个过程称为“DNS查询”,需要花费一定的时间。
- 客户端与服务器进行三次握手建立连接。
- 建立连接后,客户端会发送有真正含义的请求报文。
- 服务器接收到请求后开始处理。
- 服务器处理完毕后,发送响应给客户端。
- 客户端收到响应后,与服务器进行四次挥手,断开连接。
从上面的流程可以看出来,真正的有业务意义的阶段是“请求-处理-响应”,其他阶段时间消耗都是与业务无关的。因此可以从这上面思考如何优化TCP性能。
3.TCP连接性能聚焦
TCP连接的性能通常从下面5个方面考虑:
- TCP建立握手
- 捎带确认的TCP延迟确认算法
- TCP慢启动的拥塞控制
- 数据聚集的Nagle算法
- TIME_WAIT时延与端口耗尽
3.1 TCP建立握手
从上面的图中可以看出,一次正常的交互需要经过DNS查询、握手、挥手等与数据传输无关的操作。如果每次传输的数据都很少,那么这种操作所占用的比例就会增加,这将大大降低HTTP的性能。由于HTTP是建立在TCP连接的基础上的,所以握手的过程是对HTTP不可见的,HTTP只能看到建立连接发生了时延。三次握手的过程这里不做赘述,感兴趣的请查阅相关资料。
三次握手简单来说是建立连接前的三次交互来确认连接可以建立,有SYN,ACK+SYN,ACK三次报文通信。对于一些小的HTTP事务,比如握手后告知页面304了,这种事务中在TCP建立上可能会法费一半甚至更多的时间。
解决方案:我们可以通过重用TCP连接来减少这种性能上的损失,比如持久连接。
3.2 延迟确认
因特网是无法保证数据可靠传输的,因为在网络路由超负荷的情况下,允许丢弃任意网络分组。所以,TCP实现了一套自己的确认机制来保障数据可靠传输。
每个TCP段都有一个序号和数据校验和,接受者在接受完整之后会向发送者送回确认分组,这样保证了这个分组的可靠传输。如果发送者在一定时间窗口内没有接收到响应的确认分组,则认为这个分组已经丢失,对该分组进行重发。
由于确认报文很小,所以TCP允许在发往相同方向的数据分组中对其进行“捎带”,就是这种捎带出了问题。TCP将返回确认信息与输出信息集合在一起,可以有效的利用网络连接。因此为了找到相同方向的数据分组来进行捎带,很多TCP栈实现了一种“延时确认”的算法。这种算法将确认信息放入缓冲区,在一定的时间窗口内(一般是100-200毫秒)找不到输出分组,则对确认数据进行单独发送。
如果请求响应并没有较多的数据传输过程,则满足捎带确认的可能性就很低。通常,延迟确认算法会引入相当大的时延。
解决方案:根据操作系统的不容,可以调整或禁止延迟确认算法。
3.3 慢启动与拥塞控制
TCP传输过程有慢启动与拥塞控制的概念。

TCP在建立连接开始的时候,会进行慢启动,数据窗口会逐渐指数变大,在达到阈值后会线性增长。当发生某次超时之后,会迅速减小窗口到最小,重新开始慢启动,通知减小之前的阈值。
在这种机制的保障下,一个TCP连接是会进行自我调整的,因此一个新的连接的传输效率是不如老连接的。
解决方案:我们通过重用连接,可以使得传输效率提升,比如持久连接。
3.4 Nagle算法与TCP_NODELAY
Nagle算法与延时确认算法有些类似。不过Nagle算法关注的是发送方,为了保证不大量发送小的数据报文造成3.1的问题。该算法鼓励每次发送大的数据组,如果数据分组不够大,则放在缓存区等待与其他数据分组结合起来达到上限后一起发送,或者其他分组被确认后发送。
而对于一些小的数据分组而言,可能很多个也无法攒够一次发送的数量。当这时接收端也采用延时确认算法之后,事情就变得恐怖了。对于发送端而言,很多小的数据分组没有成功发送,因为第一个分组发送之后,服务端进行了延时确认200ms,在这段时间过去之后发送端的第二个分组才会被发送,这样的排队阻塞简直是噩梦。
解决方案:可以在协议栈中设置TCP_NODELAY来禁用Nagle算法。
3.5 TIME_WAIT时延与端口耗尽
当一个TCP连接完成四次挥手关闭之后,会进入TIME_WAIT状态,在等待2MSL之后会释放该TCP连接。因为TCP的分组可能不是按照顺序到达的,我们假设一个分组在网络中最多存货1MSL,则2MSL之后基本上就可以认为确实结束了。如果在2MSL之间服务端没有接收到LAST_ACK发送的FIN对应的响应,则TIME_WAIT会再次发送ACK。
之前有说过,一个TCP可以通过下面四个属性来确认。
<源IP地址,源端口号,目的IP地址,目的端口号>
而对于一个服务来说,之后源端口是不确定的,因为每次源端口都是随机生成的。但是源端口是有数量限制的,比如60000个端口,MSL是60秒。则连接速率就被限制在60000/120=500次/秒。如果不进行相关的优化,操作系统就无法发起更多的连接。
解决方案:可以增加请求端机器,通过负载均衡的方法降低端口耗尽的可能性,或者在服务端使用几个虚拟IP增加连接的组合。
4 总结
HTTP建立在TCP的基础上,如果我们在工作中发现HTTP建立连接的效率很低,可以考虑从上面的五个角度分析是否达到了相关的瓶颈,并通过推荐方案解决问题。
高效管理http连接的更多相关文章
- 灵活使用ssh、dsh和pssh高效管理大量计算机
http://os.iyunv.com/art/201012/240113.htm 灵活使用ssh.dsh和pssh高效管理大量计算机 http://os.iyunv.com2010-12-23 09 ...
- 关于Kafka java consumer管理TCP连接的讨论
本篇是<关于Kafka producer管理TCP连接的讨论>的续篇,主要讨论Kafka java consumer是如何管理TCP连接.实际上,这两篇大部分的内容是相同的,即consum ...
- 关于Kafka producer管理TCP连接的讨论
在Kafka中,TCP连接的管理交由底层的Selector类(org.apache.kafka.common.network)来维护.Selector类定义了很多数据结构,其中最核心的当属java.n ...
- 创建JDBC模板简化代码、JDBC应用的事务管理以及连接池的作用
一.创建JDBC模板简化代码 一个简单的查询.要做这么一大堆事情,并且还要处理异常,我们不防来梳理一下: 1.获取connection 2.获取statement 3.获取resultset 4 ...
- 高效管理 Elasticsearch 中基于时间的索引——本质是在利用滚动模式做数据的冷热分离,热索引可以用ssd
高效管理 Elasticsearch 中基于时间的索引 转自:http://stormluke.me/es-managing-time-based-indices-efficiently/ 用 Ela ...
- 代码管理——如何连接Git Server,下载代码
最近一个项目需要与国外团队合作,而他们的代码在GitLab上,需要使用Git工具连接服务器,对于我这样一个SVN的拥护者,当然很高兴去接受这个工作了(鄙视一下目前单位还使用ClearCase). 但操 ...
- 通过LRU实现通用高效的超时连接探测
编写网络通讯都要面对一个问题,就是要把很久不存活的死连接清除,如果不这样做那死连接最终会占用大量内存影响服务运作!在实现过程中一般都会使用ping,pong原理,通过ping,pong来更新连接的时效 ...
- 使用ssh config配置文件来管理ssh连接
我本人其实及其烦使用配置文件这种东西,有时候看到巨大又复杂的配置文件,甚至复杂过代码的时候,总感觉设计配置文件的人有些本末倒置. 但是ssh这个配置文件真的非常简单好用,让我稍微体验了一次配置文件使用 ...
- 服装盘点机PDA在服装行业颜色尺码仓库条码高效管理应用
服装行业的商品管理的特点是需要管理颜色和尺码 具体逻辑就是: 什么商品,什么颜色,什么尺码,入库多少个? 什么商品,什么颜色,什么尺码,出库多少个? 什么商品,什么颜色,什么尺码,还有库存多少个? 如 ...
随机推荐
- K - Kia's Calculation (贪心)
Kia's Calculation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- C++求出旋转数组的最小数字
今天遇到这么一道题目,感觉很有意思,要记下来! 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4 ...
- 逆向课程第二讲,寻找main入口点
逆向课程第二讲,寻找main入口点 一丶识别各个程序的入口点 入门知识,识别各个应用程序的入口点 (举例识别VC 编译器生成,以及VS编译生成的Debug版本以及Release版本) 1.识别VC6. ...
- Java一点输入输出技巧
输入: 格式1:Scanner sc = new Scanner(System.in); 格式2:Scanner sc = new Scanner(new BufferedInputStream(Sy ...
- 网页头部 lang的声明
1. 简体中文页面:html lang=zh-cmn-Hans2. 繁体中文页面:html lang=zh-cmn-Hant3. 英语页面:html lang=en 4. <回来>的音频, ...
- HTML DOM应用案例1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Luogu P2183 巧克力
题目描述 佳佳邀请了M个同学到家里玩.为了招待客人,她需要将巧克力分给她的好朋友们.她有N(1<=N<=5000)块巧克力,但是大小各不一样,第i块巧克力大小为为1*Xi(1<=i& ...
- 【WEB API项目实战干货系列】- API访问客户端(WebApiClient适用于MVC/WebForms/WinForm)(四)
这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前最新的代码已经通过Sqlite + NHibernate + Autofac满足了我们基本的 ...
- 强大又简单的响应式框架——Foundation 网格系统
前端框架——Foundation 简介 Foundation 用于开发响应式的 HTML, CSS and JavaScript 框架. Foundation 是一个易用.强大而且 ...
- 史上最完整的PS快捷键(绝对经典)
快速恢复默认值 有些不擅长Photoshop的朋友为了调整出满意的效果真是几经周折,结果发现还是原来的默认效果最好,这下傻了眼,后悔不该当初呀!怎么恢复到默认值呀?试着轻轻点按选项栏上的工具图标,然后 ...