前言css
在前一篇随笔《大型网站系统架构的演化》中,介绍了大型网站的演化过程,期间穿插了一些技术和手段,咱们能够从中看出一个大型网站的轮廓,但想要掌握设计开发维护大型网站的技术,须要咱们一步一步去研究实践。因此我打算写一个系列,从理论到实践讲述大型网站的点滴,这也是一个共同窗习的过程,但愿本身能坚持下去。系列大概会分为两部分,理论和实践,理论部分尽可能通俗易懂,也要讲一些细节。实践部分会抽取一些技术作实践,将方法、解决问题过程分享出来。html
本文将讲述大型网站中一个重要的要素,性能。java
什么是性能web
有人说性能就是访问速度快慢,这是最直观的说法,也是用户的真实体验。一个用户从输入网址到按下回车键,看到网页的快慢,这就是性能。对于咱们来讲,须要去挖掘这个过程,由于这决定咱们怎么去作性能优化。算法
这中间发生了什么?数据库
用户访问网站的整个流程:用户输入网站域名,经过DNS解析,找到目标服务器IP,请求数据经互联网达到目标服务器,目标服务器收到请求数据,进行处理(执行程序、访问数据库、文件服务器等)。处理完成,将响应数据又经互联网返回给用户浏览器,浏览器获得结果进行计算渲染显示给用户。浏览器
咱们把整个过程,分为三段路径:缓存
一、第一段在用户和浏览器端,主要负责发出用户请求,以及接受响应数据进行计算渲染显示给用户;性能优化
二、第二段在网络上,负责对请求数据、响应数据的传输;服务器
三、第三段在网站服务器端,负责对请求数据进行处理(执行程序、访问数据库、文件等),并将结果返回;
第一路径
第一路径花费的时间包括输入域名发起请求的时间和浏览器收到响应后计算渲染的时间。
输入域名发起请求,实质过程是:
一、用户在浏览器输入要访问的网站域名;
二、本地DNS请求网站受权的DNS服务器对域名进行解析,并获得解析结果即IP地址(并将IP地址缓存起来)。
三、向目标IP地址发出请求。
从这个过程咱们能够看到,优化的地方主要是减小DNS解析次数,而若是用户浏览器设置了缓存,则再第二次访问相同域名的时候就不会去请求DNS服务器,直接用缓存中的IP地址发出请求。所以这个过程主要取决于浏览器的设置。如今主流的浏览器默认设置了DNS的预取功能(DNS Prefetch),固然你也能够主动告知浏览器个人网站须要作DNS预取:
<meta http-equiv="x-dns-prefetch-control" content="on" />
浏览器将数据进行计算渲染的过程:
一、浏览器解析响应数据;
二、浏览器建立DOM树;
三、浏览器下载CSS样式,并应用到DOM树,进行渲染;
四、浏览器下载JS文件,开始解析执行;
五、显示给用户。
从这个过程,咱们能够找出很多能够优化的地方。首先咱们能够尽可能控制页面大小,使得浏览器解析的时间更短;而且将多个CSS文件、JS文件文件合并压缩减小文件下载的次数和大小;另外注意将CSS放在页面前面,JS访问页面后面,这样便于页面首先能渲染出来,再执行js脚本,对于用户来讲有更好的体验。最后我还能够设置浏览器缓存,下次访问时从缓存读取内容,减小http请求。
<meta http-equiv="Cache-Control" content="max-age=5" />
该代码说明了浏览器启用了缓存并在5秒内不会再次访问服务器。注意缓存的设置须要结合你的业务特性来适当配置。
如下是京东商城的HTML简图:
css样式放在html前面,而且进行了合并。
大多数的JS文件放在页尾。
第二路径
第二路径在网络上,花费的时间一样包括请求数据的传输时间和响应数据的传输时间,这个两个时间取决于数据传输的速度,这里咱们要讲一个名词“带宽”。什么是带宽,咱们常常说带宽10M,20M是什么意思?个人带宽20M,这意味着什么?咱们知道带宽速度分为上行、下行速度,也就是上传和下载的速度。带宽20M对于用户来讲则是下载速度20M(20×1024×1024比特率),换算成字节20M/8=2.5M。也就是说20M的带宽下载速度理论可达2.5M/s,而对于家庭用户而言上传速度通常比下载速度小的多,大约是不到十分之一。而对于网站服务器(企业用户)来讲,则否则,通常上行速度等于下载速度。这也是运营商根据实际需求分配的,毕竟用户的主要需求是下载数据,而不是上传数据。
整个流程从传输方式看就是:用户发送请求数据(上传),网站服务器接受请求数据(下载),网站服务器返回响应数据(上传),用户接受响应数据(下载)。对于用户来讲,上传数据是很小的(Url参数),而下载数据是较大的(响应数据);对于服务器来讲,下载数据是很小的(url参数),上传数据是较大(响应数据)。理解了这个,咱们能够解释为何有时用户反映为何本身的带宽足够,但打开某些网站仍然很慢,就是由于尽管用户的下载速度很快,但网站服务器的上传速度很慢,这就像一个抽水管和一个出水管,无论抽水管再大,但出水管很小,一样抽到的水量是有限的。了解了这个原理咱们来看怎么提升数据传输的速度,首先用户的上传、下载速度咱们是没法决定的,咱们能决定的是网站服务器的上传、下载速度,因此咱们能够作的是适当的增长服务器带宽(带宽是很贵的,盲目的增长只会增长没必要要成本)。购买合适的带宽须要根据网站业务特性、规模以及结合运维人员的经验来选择。一般能够考虑的算法,即根据一次响应数据的大小,乘以PV数,除以对应的高峰时间段,从而大体估算出网站带宽的需求。
下面咱们继续进一步研究第二路径:
上图表示用户访问网站服务器时网络的大体状况,从图上能够看出假设网站服务器从电信网络接入,而用户A做为电信的宽带用户,则能够经过电信骨干网快速的访问到网站服务器。用户B,用户C做为移动和联通用户须要经过运营商的互联互通通过较长路径才能访问到服务器。
针对这种状况,咱们能够采起如下方法来优化:
一、在各运营商发达的地区的IDC(互联网数据中心,能够理解成机房)部署网站服务器,各运营商的用户便可经过各自的骨干网访问服务器。
二、购买代理服务,也就是原来联通用户须要经过联通骨干网——>联通互联互通路由器——>电信骨干网——>网站服务器的过程。经过代理服务,代理服务器直连到电信骨干网,访问网站服务器。
二、在主要地区城市购买CDN服务,缓存对应的数据,用户可先从最近的CDN运营商获取请求数据。
第三路径
第三路径主要是网站服务器内部处理的过程,当中包括执行程序、访问文件、数据库等资源。
这是对于咱们来讲最能够发挥的地方:
一、使用缓存,根据须要使用本地缓存或分布式缓存;
二、使用异步操做,这种方式不只能够提升性能,也提升了系统的扩展性;
三、代码优化;
四、存储优化;
缓存
若是缓存数据较少,能够利用OSCache实现本地缓存:
当缓存数据过多时,利用Memcached实现分布式缓存:
Memcached实现分布式缓存,缓存服务器之间是互不通讯的,也就是咱们能够方便的经过增长Memcached服务器对系统进行扩展。
异步操做
使用同步请求的方式,在高并发的状况下,会对数据库形成很大的压力,也会让用户感受响应时间过长。异步请求方式,则能够快速的对用户作出响应,而具体的数据库操做请求,则经过消息队列服务器发送给数据库服务器,作具体的插入操做。插入操做的结果则已其余方式通知客户端。例如通常在订票系统当中,出票行为就是异步完成,最终的出票结果会以邮件或其余方式告知用户。
代码优化
这里就不在详细描述,另外一篇随笔《怎样编写高质量的java代码》对代码质量和风格作过大体的介绍,有兴趣能够看一下。
存储优化
大型网站中海量的数据读写对磁盘形成很大压力,系统最大的瓶颈仍是在磁盘的读写。能够考虑使用磁盘阵列、分布式储存来改善存储的性能。
性能的指标和测试
上面经过解析用户访问网站的过程来思考怎么提升用户感知的性能,对于用户来言性能就是快和慢。但对于咱们来讲,不能这样简单描述,咱们须要去量化他,用一些数据指标去衡量它。这里讲到几个名词:响应时间、并发量、吞吐量。
响应时间:就是用户发出请求到收到响应数据的时间;
并发量:就是系统同时能处理多少用户请求;
吞吐量:就是单位时间内系统处理的请求数量;
为了通俗的了解这三个概念,咱们以高速公路的收费站为例子:响应时间是指一辆车通过收费站的时间,也就是车辆从进入收费站、付钱、开闸、离开收费站的时间;并发量是指这个收费站同时能通行多少辆车,能够理解为收费站的出口数量。吞吐量是指:在一段时间内,这个收费站通往了多少了车。
这个例子不晓得恰不恰当。
对于性能测试来讲,基本也是围绕这些方面来测试,下图说明了性能测试的过程:
左图表示响应时间和并发用户量的二维坐标图,从图上能够看出,并发用户量在必定量增长时,响应时间很短,而且没有太大的起伏,这表示系统目前处于平常运行期,能够很快处理用户请求(A点以前);随着并发量的增长,系统处于请求高峰期,但仍然能够有序的处理用户请求,响应时间较平常有所增长(A、B之间);当并发量增长到必定数量时,超过了系统的负载能力,系统处于濒临崩溃的边缘(B、C之间),响应时间严重过长,直到系统崩溃。
右图表示吞吐量与并发用户量的二维坐标图,能够看出,随着并发用户量的增长,吞吐量逐渐增长;在并发量到达必定量时,因为系统处理能力达到最大,吞吐量增长放缓;当并发量超过系统负载时(E点),系统处理能力开始降低,不能再请求增长的用户请求,吞吐量反而下降。
小结
本文经过用户访问网站的过程,分析了三个路径过程当中提升性能的想法和手段,最后介绍了描述性能的指标,并对性能测试作了简要说明。
参考资料:
《海量运维运营规划》
《大型网站技术架构》
《构建高性能web站点》