《构建高性能Web站点》



       1.1  等待的真相

    整个过程听起来好像并不复杂,也许你从来都没有考虑过在这段等待的时间里世界都发生了什么变化,也许你早已习惯了利用这段时间东张西望或者品尝零食,或者你根本没有来得及意识到这点,新的网页就已经闪亮登场,恭喜你,你很幸运!但是在这个世界上,幸运儿永远只占少数,大多数人的大脑处理速度已经让他们明显感觉到这段等待时间漫长无比,久经考验的他们可以随时身手敏捷地打开多个浏览器窗口与时间赛跑,并为此筋疲力尽。

    另一方面,对于站点经营者来说,让用户等待的时间过长,也许会造成毁灭性的后果。我见过很多人为了享用某家特色小吃而在餐馆门口乐此不疲地排着长队,但没有听说有多少用户执着地等待着一个速度缓慢的站点而不去尝试别的站点。

    在这段等待的时间里,到底发生了什么?事实上这并不简单,大概经历了以下几部分时间:

    ? 数据在网络上传输的时间

    ? 站点服务器处理请求并生成回应数据的时间

    ? 浏览器本地计算和渲染的时间

    数据在网络上传输的时间总的来说包括两部分,即浏览器端主机发出的请求数据经过网络到达服务器的时间,以及服务器的回应数据经过网络回到浏览器端主机的时间。这两部分时间都可以视为某一大小的数据从某主机开始发送一直到另一端主机全部接收所消耗的总时间,我们称它为响应时间,它的决定因素主要包括发送的数据量和网络带宽。数据量容易计算,但是究竟什么是带宽呢?我们将在后续章节中详细介绍带宽的本质。

    站点服务器处理请求并生成回应数据的时间主要消耗在服务器端,包括非常多的环节,我们一般用另一个指标来衡量这部分时间,即每秒处理请求数,也称吞吐率,注意这里的吞吐率不是指单位时间处理的数据量,而是请求数。影响服务器吞吐率的因素非常多,比如服务器的并发策略、I/O模型、I/O性能、CPU核数等,当然也包括应用程序本身的逻辑复杂度等。这些将在后续章节中详细介绍。

    浏览器本地计算和渲染的时间自然消耗在浏览器端,它依赖的因素包括浏览器采用的并发策略、样式渲染方式、脚本解释器的性能、页面大小、页面组件的数量、页面组件缓存状况、页面组件域名分布以及域名DNS解析等,并且其中一些因素随着各厂商浏览器版本的不同而略有变化。这部分内容我们在后续章节中也会适当提到。

    可见,一个页面包含了若干个请求,每个请求都或多或少地涉及以上这些过程,假如有一处关键环节稍加拖延,整体的速度便可想而知。

    现在,如果有用户向你抱怨在打开站点首页的时候等待了很久,你知道究竟慢在哪里了吗?

    1.2  瓶颈在哪里

    相信你一定知道赤壁之战,这是中国历史上一场着名的以少胜多的战役,东吴的任务是击退曹操的进攻,要完成这项任务,可谓“万事俱备,只欠东风”,这时东风便是决胜的瓶颈,所以很多系统论研究专家将其称为“东风效应”,也就是社会心理学里讲的“瓶颈效应”。

    之所以称它为瓶颈,是因为尽管东吴做了很多的战前准备,包括蒋干中计导致曹操错杀蔡瑁和张允、诸葛亮草船借箭、东吴苦练水军等,但是仅靠这些仍无法获得最终胜利,还需要最后的东南风才能一锤定音,完成火烧曹军战船的计划。不过之前的准备工作都是胜利的子因素,而东南风这个关键因素最终和其他子因素一起相互作用,将整个战斗的杀伤力无限放大。

    曹操运气不好,遇上东南风,倒了大霉,曹军战船一片火海,这时候东吴需要派出勇猛的陆军部队登岸攻下曹营,可是东吴向来精通水战,几乎没有强大的陆战部队,只有老将黄盖,这如何与曹操的精英骑兵抗衡呢?这个时候决胜的关键因素变成了刘备的盟军支援,五虎上将各个威猛无比,身怀必杀绝技,此时正是上岸一显身手的好机会,他们不费吹灰之力就将曹军打得落花流水,试想如果没有刘备的支援,赤壁一战胜败可能就扑朔迷离了。

    可见,系统性能的瓶颈,是指影响性能的关键因素,这个关键因素随着系统的运行又会发生不断的变化或迁移,比如由于站点用户组成结构的多样性和习惯的差异,导致在不同时段系统的瓶颈各不相同,又如站点在数据存储量或浏览量增长到不同级别时,系统瓶颈也会发生迁移。一旦找到真正影响系统性能的主要因素,也就是性能瓶颈,就要坚决对其进行调整或优化,因为你不得不这么做。

    提示:

    中医是一门关于生命的哲学,也是中国人智慧的结晶,它的光芒在于独到的思辨能力和系统性的分析方法,它认为世间万物都在不停地变化,并赋予它们阴阳状态,包括天地、季节、天气、心理、生理等,而患者的病理也在随之变化,所以,中医会对同一位患者在不同季节进行不同的诊断,找到不同的病因。

    同时,在这些关键因素的背后,也存在很多不能忽略的子因素,构成了性能优化的“长尾效应”,也就是说如果你对某个子因素背后的问题进行优化,可能会带来性能上的少许提升,也许不被察觉,但是多个子因素的优化结果也许会叠加在一起,带来性能上可观的提升。对于诸多子因素的优化,需要稍加谨慎,花点时间考虑这种优化是否值得,以及是否会带来潜在的副作用,还有其他依赖的非技术因素。

    然而,不论是关键因素还是子因素,它们的背后都是影响系统性能的问题所在,问题本身并不涉及关键性,只有在不同的系统和应用场景下,才会显示出其是否关键。

    本章的其余部分将先列出一些我们经常遇到的问题,并简单介绍我们常用的优化方案,至于这些问题在什么时候是否关键,它们的本质是什么,以及如何调整或优化,在后续章节中我们将结合具体场景来详细探讨包括这些在内的更多主题,这也是本书贯穿始终的线索。

    1.3  增加带宽

    当Web站点的网页或组件的下载速度变慢时,一些架构师可能想到的最省事的办法就是增加服务器带宽,因为他们认为是服务器带宽不够用了,对于一些以提供下载服务为主的站点来说也许是这样的,但是对于其他服务的站点,你知道站点当前究竟使用了多少带宽吗?这些带宽都用到哪里了呢?如何计算站点现在和可预见未来使用的带宽?带宽增加后下载速度就可以加快吗?使用独享带宽和共享带宽的本质区别是什么?如何节省带宽?还有,你可能会忍无可忍地问,究竟什么是带宽?

    对于带宽的概念,如果你没有仔细阅读计算机网络教材中的描述,我敢肯定你一定是完全凭借自己的理解来认识它的,因为这个词实在是太有创意了,也实在太容易从字面理解了,但是这些认识从本质上讲是完全错误的,正是基于这种误解,很多人都无法完全解答上述那一连串问题,导致在所有涉及带宽的问题上,只能依靠经验和猜想。

    在后续章节中,我们将通过介绍数据的网络传输原理,彻底揭开带宽的本质,以及数据传输响应时间的依赖因素和计算方法。搞清楚这些一点都不困难,它们是一个优秀架构师必须掌握的基础知识。

    1.4  减少网页中的HTTP请求

    我们知道Web站点中几乎任何一个网页都包含了多个组件,每个组件都需要下载、计算或渲染,毫无疑问,这些行为都会消耗时间。那么如果可以让网页减少这些行为,应该就可以加快网页的展示速度,这是毫无疑问的,但是往往我们需要在优雅的网页表现和性能之间权衡取舍,这也许是美和快之间的博弈,找到最优的均衡点至关重要,我们为此做了很多尝试和努力:

    ? 设计更加简单的网页,使其包含较少的图片和脚本,但是这可能牺牲了美观和用户交互。

    ? 将多个图片合并为一个文件,利用CSS背景图片的偏移技术呈现在网页中,避免了多个图片的下载。

    ? 合并JavaScript脚本或者CSS样式表。

    ? 充分利用HTTP中的浏览器端Cache策略,减少重复下载。

    很显然,这些技巧都来自于Web网页前端的优化,在后续章节中我们会有所涉及,但是不作为本书的重点来介绍,本书将更加偏重于站点服务器端的性能改善和规模扩展。

    1.5  加快服务器脚本计算速度

    我想大多数涉及性能问题的站点都会使用各种各样的服务器端脚本语言,比如主流的PHP、Ruby、Python、ASP.NET、JSP等,这些脚本语言用来编写动态内容或者后台运行的小程序,已经成了几乎所有站点的首选。而曾经使用C++编写动态内容的经历也让我记忆犹新,除了每天都在感叹C++的严谨和优雅之外,我找不到其他任何好处。

    我们知道,用这些脚本语言编写的程序文件需要通过相应的脚本解释器进行解释后生成中间代码,然后依托在解释器的运行环境中运行。所以生成中间代码的这部分时间又成为大家为获取性能提升而瞄准的一个目标,对于一些拥有较强商业支持的脚本语言,比如ASP.NET和JSP,均有内置的优化方案,比如解释器对某个脚本程序第一次解释的时候,将中间代码缓存起来,以供下次直接使用。

    对于开源类的脚本语言,也有很多第三方组件来提供此类功能,比如PHP的APC组件等。使用这些组件进行脚本优化真的那么有用吗?不同的应用效果是否有所不同呢?在后续章节中我们会详细探讨。

你可能感兴趣的:(Web)