KimmyKuang +

《HTTP权威指南》读书笔记(一)

HTTP协议是应用层协议,需要依赖于TCP传输层,所以当客户端每次打开一条HTTP连接去服务器端请求资源时,双方都会先建立一个TCP连接;而TCP连接是会有时延的,比如需要三次握手才能成功建立连接,建立好的新连接也会有TCP慢启动时延问题等。

串行的HTTP连接无疑是比较浪费时间的一种实现方式,每条请求都需要等上一条执行完毕才能发起,如若再碰到一些含有复杂逻辑的js脚本的话,可能会导致后续资源一直处于等待加载状态,整个页面一片空白,用户体验是非常不好的。

并行连接

并行连接指的是HTTP允许客户端打开多条连接,并行地执行多个HTTP事务,现代浏览器一般都支持并行连接,IE6是并发2个,IE8好像是8个,Chrome和Firefox也在很早的版本中就开始支持并发连接。

但是打开多个并行连接本身是会有性能消耗的,考虑到如果客户端处于一个带宽不足的网络中,并发执行请求反而会导致多个HTTP请求竞争带宽资源的情况出现,加载速度可能提升很小甚至更慢。

而从web服务器角度考虑也不会允许客户端并发大量请求。因为web服务器需要同时响应处理很多其他用户的请求,如果一个用户并发了100个连接,那么100个用户同时请求就会产生10000个连接,对于web服务器的性能会造成严重下降。所以一般浏览器的并行连接数从2个到16个不等。

持久连接

持久连接是指在一条HTTP事务处理完后tcp连接不关闭,等待下一次HTTP请求复用,以节省TCP请求开销和慢启动时延等消耗;非持久连接每次事务结束后就关闭TCP连接。

持久连接会一直保持连接状态,直到客户端或服务端关闭。持久连接如果管理不当的话,会造成大量空闲连接的累积,连接保持持久状态也是会有消耗的。

并行连接配合持久连接是现代浏览器主要使用的方式,一般都会打开有限个并行连接,每个并行连接都是持久连接。

持久连接有两种类型,第一个是在HTTP/1.0协议中就开始支持的keep-alive,直到现在的HTTP/1.1协议中还是被普遍使用着,第二个是HTTP/1.1开始支持的persisten,但是观察了下国内的一些网站,好像很少被使用,因为HTTP/1.1默认是打开了持久连接的,所以还是keep-alive用的比较多。

客户端可以通过一条包含Connection: keep-alive首部的连接申明该连接是持久连接,还有一个Keep-Alive首部Keep-Alive: max=5, timeout=120,表明持久连接的超时规则。HTTP/1.0持久连接不是默认打开的,所以需要用这个首部来显示声明,而在HTTP/1.1是默认打开的,不用加上这个首部也可以,但是一般都还是会带上。

需要注意的是Connection首部是一个逐跳首部,只能在相邻的两个路由之间跳动,如果在客户端和服务端之间有多个代理中继,那么需要每个代理都能“聪明”地理解Connection首部的含义,否则如果只是盲目地转发首部而不理解这是一个keep-alive连接的话,会造成“哑代理”现象:代理不认识Connection:keep-alive首部,不知道客户端希望打开持久连接,结果就是那个代理在发送完客户端的请求后,一直在等待服务端回传Connection:close关闭以连接;然而客户端以为持久连接已经打开了,所以继续复用这条TCP连接,但是中间的那个“哑代理”是不会认的,直接丢弃了第二条HTTP请求。

Blog

Articles