keep-alive可以让TCP连接被复用,避免不必要的断开与重新连接。从这个设定上看它绝对是个好东西,但并不是所有连接都适合用keep-alive。在不适合keep-alive的场景使用keep-alive反而会带来负面影响。它实际上就是一种以内存换取网络的策略。
当一个页面打开时,页面需要请求js、css以及页面上的图片等。网络请求是需要时间的,这些请求不会瞬间完成,但他们却是瞬间发起的。浏览器的并发数限制一般允许6个并发请求,客户端需要的前6个资源会被同时使用不同的连接向服务器发起请求。如果服务器对所有请求都使用keep-alive,那么打开一个页面就相当于建立6个长连接。如果页面上需要加载的资源很多,或者程序有多个连接同时使用的需求,这个6个连接当然可以有效的复用。但如果需要加载的资源少于6个呢?这就意味着,这些连接一次都不会被复用到,而服务器却需要维持这个连接。这种情况keep-alive就没有作用了。
普通的网页通常都会超过6个资源需要加载,网页中存在大量图片是很正常的。但如果这资源开启了cache,也就是说页面二次访问时他们不会重新发起请求,那么页面需求的资源就很有可能小于6个,这种情况下keep-alive就成了个累赘。所以使用keep-alive时也要考虑缓存方面的设置,对于特殊的情况可能需要服务器判断是否要为特定连接使用keep-alive。
keep-alive可以自己控制超时的时间。注意这个时间不是整个连接的寿命,而是当这个连接空闲那么个时间后自动断开。对于普通的静态资源请求使用5到15秒超时的keep-alive比较合适,这些时间主要用于弥补网络延迟。浏览器对这些资源的访问是接踵而至的,中间几乎不会有间隔的时间,所以完全没必要太长的超时。对于一些程序连接也同样可以使用这样的短超时,比如上一篇文章中的keep-alive和长轮询一起使用的情况。总之,只要请求是接连不断的向服务器发起的,超时就没必要太长。
对于特定的程序,也可以设置个比较长的超时。这种情况就应该考虑一个成本问题。是先断开连接等到需要时重新建立,还是让服务器维持一段时间的连接。前者的开销在于网络,后者的开销在于内存,这就比较不好把握了。比如一个瀑布流的页面,滚动条拖到末尾会自动加载内容,这时可能就会用一个超时比较长的keep-alive,因为用户很可能会继续加载更多,但是在此之前会先浏览已经加载了的数据。
最后总结一下,在请求多而连续时适合使用keep-alive,其它情况一般没必要使用,如果非要使用就得斟酌超时的设定。
当一个页面打开时,页面需要请求js、css以及页面上的图片等。网络请求是需要时间的,这些请求不会瞬间完成,但他们却是瞬间发起的。浏览器的并发数限制一般允许6个并发请求,客户端需要的前6个资源会被同时使用不同的连接向服务器发起请求。如果服务器对所有请求都使用keep-alive,那么打开一个页面就相当于建立6个长连接。如果页面上需要加载的资源很多,或者程序有多个连接同时使用的需求,这个6个连接当然可以有效的复用。但如果需要加载的资源少于6个呢?这就意味着,这些连接一次都不会被复用到,而服务器却需要维持这个连接。这种情况keep-alive就没有作用了。
普通的网页通常都会超过6个资源需要加载,网页中存在大量图片是很正常的。但如果这资源开启了cache,也就是说页面二次访问时他们不会重新发起请求,那么页面需求的资源就很有可能小于6个,这种情况下keep-alive就成了个累赘。所以使用keep-alive时也要考虑缓存方面的设置,对于特殊的情况可能需要服务器判断是否要为特定连接使用keep-alive。
keep-alive可以自己控制超时的时间。注意这个时间不是整个连接的寿命,而是当这个连接空闲那么个时间后自动断开。对于普通的静态资源请求使用5到15秒超时的keep-alive比较合适,这些时间主要用于弥补网络延迟。浏览器对这些资源的访问是接踵而至的,中间几乎不会有间隔的时间,所以完全没必要太长的超时。对于一些程序连接也同样可以使用这样的短超时,比如上一篇文章中的keep-alive和长轮询一起使用的情况。总之,只要请求是接连不断的向服务器发起的,超时就没必要太长。
对于特定的程序,也可以设置个比较长的超时。这种情况就应该考虑一个成本问题。是先断开连接等到需要时重新建立,还是让服务器维持一段时间的连接。前者的开销在于网络,后者的开销在于内存,这就比较不好把握了。比如一个瀑布流的页面,滚动条拖到末尾会自动加载内容,这时可能就会用一个超时比较长的keep-alive,因为用户很可能会继续加载更多,但是在此之前会先浏览已经加载了的数据。
最后总结一下,在请求多而连续时适合使用keep-alive,其它情况一般没必要使用,如果非要使用就得斟酌超时的设定。