高并发Web服务的演变 - 节约系统内存和CPU
原文 http://linux.cn/article-5294-1-rss.html
一、越来越多的并发连接数
现在的Web系统面对的并发连接数在近几年呈现指数增长,高并发成为了一种常态,给Web系统带来不小的挑战。以最简单粗暴的方式解决,就是增加 Web系统的机器和升级硬件配置。虽然现在的硬件越来越便宜,但是一味地通过增加机器来解决并发量的增长,成本是非常高昂的。结合技术优化方案,才是更有 效的解决方法。
并发连接数为什么呈指数增长?实际上,从这几年的用户基数上看,这个数量并没有出现指数增长,因此它并非主要原因。主要原因,还是web变得更复杂,交互更丰富所导致的。
1. 页面元素增多,交互复杂
Web页面元素越来越多,更为丰富。更多的资源元素,意味着更多的下载请求。Web系统的交互越来越复杂,交互场景和次数也大幅增加。以 “www.qq.com”的首页为例子,刷新一次,大概会有244个请求。并且,在页面打开完成之后,还会有一些定时的查询或者上报请求持续运作。
目前的Http请求,为了减少反复的创建和销毁连接行为,通常都建立长连接(Connection keep-alive)。一经建立,这个连接 会被保持住一段时间,被后续请求复用。然而,它也带来了另一个新的问题,连接的保持是会占用Web系统服务端资源的,如果不充分使用这个连接,会导致资源 浪费。长连接被创建后,首批资源传输完毕,之后几乎没有数据交互,一直到超时时间,才会自动释放长连接占据的系统资源。
除此之外,还有一些Web需求本身就需要长期保持连接的,例如Web socket。
2. 主流的本浏览器的连接数在增加
面对越来越丰富的Web资源,主流浏览器并发连接数也在增加,同一个域下,早期的浏览器一般只有1-2个下载连接,而目前的主流浏览器通常在 2-6个。增加浏览器并发连接数目,在需要下载资源比较多的场景下,可以加快页面的加载速度。更多的连接对浏览器加载页面元素是有好处的,在某些连接遭遇 “网络阻塞”的情况下,其他正常的下载连接可以继续工作。
这样自然无形增加了Web系统后端的压力,更多的下载连接意味着占据了更多的Web服务器的资源。而在用户访问高峰期,自热而然就形成了“高并 发”场景。这些连接和请求,占据了服务器的大量CPU和内存等资源。尤其在资源数目超过100+的网站页面中,使用更多的下载连接,非常有必要。
二、Web前端优化,降低服务端压力
在缓解“高并发”的压力,需要前端和后端的共同配合优化,才能达到最大效果。在用户第一线的Web前端,可以起到减少或者减轻Http请求的效果。
1. 减少Web请求
常用的实现方法是通过Http协议头中的expire或max-age来控制,将静态内容放入浏览器的本地缓存,在之后的一段时间里,不再请求 Web服务器,直接使用本地资源。还有HTML5中的本地存储技术(LocalStorage),也被作为一个强大的数据本地缓存。
这种方案缓存后,根本不发送请求到Web服务器,大幅降低服务器压力,也带来了良好的用户体验。但是,这种方案,对首次访问的用户无效,同时,也影响部分Web资源的实时性。
2. 减轻Web请求
浏览器的本地缓存是存在过期时间的,一旦过期,就必须重新向服务器请求。这个时候,会有两种情形:
(1)服务器的资源内容没有更新,浏览器请求Web资源,服务器回复“可以继续使用本地缓存”。(发生通信,但是Web服务器只需要做简单“回复”)
(2)服务器的文件或者内容已经更新,浏览器请求Web资源,Web服务器通过网络传输新的资源内容。(发生通信,Web服务器需要完成复杂的传输工作)
这里的协商方式是通过Http协议的Last-Modified或Etag来控制,这个时候请求服务器,如果是内容没有发生变更的情况,服务器会 返回304 Not Modified。这样的话,就不需要每次请求Web服务器都做复杂的传输完整数据文件的工作,只要简单的http应答就可以达到相 同的效果。
虽然上述请求,起到“减轻”Web服务器的压力,但是连接仍然被建立,请求也发生了。
3. 合并页面请求
如果是比较老一些的Web开发者,应该会更有印象,在ajax盛行之前。页面大部分都是直接输出的,并没有这么多的ajax请求,Web后端将页 面内容完全拼凑好了,再返回给前端。那个时候,页面静态化,是一个挺广泛的优化方式。后来,被交互更友好的ajax渐渐替代了,一个页面的请求也变得越来 越多。
由于移动端的网络(2G/3G)比起PC宽带差很多,并且部分手机配置比较低,面对一个超过100个请求的网页,加载的速度会缓慢很多。于是,优化的方向又重新回到合并页面元素,减少请求数量:
(1)合并HTML展示内容。将CSS和JS直接嵌入到HTML页面内,不通过连接的方式引入。
(2)Ajax动态内容合并请求。对于动态内容,将10次Ajax请求合并为1次的批量信息查询。
(3)小图片合并,通过CSS的偏移量技术Sprites,将很多小图片合并为一张。这个优化方式,在PC端的Web优化中,也非常常见。
合并请求,减少了传输数据的次数,也就是相当于将它们从一个一个地请求,变为一次的“批量”请求。上述优化方法,到达“减轻”Web服务器压力的目的,减少了需要建立的连接。