2 服务端优化
2.1 缓存
2.1.1 数据缓存
某些动态计算的时间主要消耗在一些烦人的数据上,例如一些常数的计算。
将常用的数据缓存到内存中,可以减少I/O消耗或数据库读取。
较细粒度的数据缓存避免了过期时大量网页的整体更新时,很多动态内容都包含一段公用的数据,如果把整个页面全部缓存,那么这段数据的频繁更新导致网页的频繁过期,无疑会使得所有网页都要频繁地重建缓存。
2.1.2 动态内容缓存
为了减少动态内容的重复计算,将动态内容的输出结果缓存起来,在随后的一段时间内当有用户调用该脚本时,直接输出结果
过期检查
给动态内容引入缓存,在一定程度上避免了动态内容不必要的重复计算,缩短了请求响应时间并提高了服务器的吞吐率。但是,动态内容的目的在于提供变化的内容,所以它的缓存不可能长期有效,否则就失去了意义,所以动态内容的缓存机制必须能够判断缓存何时过期,以及何时需要生成新的缓存。
将缓存放到内存中
减少磁盘I/O的开销
局部无缓存
对于某些特殊的动态网页,需要页面中某一块区域的内容及时更新,如新闻的阅读统计量区域和评论区域。如果为了这一块区域的及时更新,就将整个页面重新创建缓存的话,有点不值得。在整页缓存的基础上,都提供局部无缓存的支持,允许在页面中指定一块包含动态数据的HTML代码段,每次调用这些动态数据都需要实时计算,然后和其余部分的缓存合成最终的网页。
2.1.3动态页面静态化
虽然动态内容缓存避免了重复计算,但是仍然要调用动态脚本解释器来判断是否使用缓存。
直接将动态内容生成的页面保存,生成静态页面,让浏览器直接访问这些静态页面。
不再通过脚本解释器。
2.1.4浏览器缓存
适合缓存的组件:不经常变换的组件
- 图片
- 脚本
- 样式表
- flash组件
不适合缓存的组件
- HTML文档:包含动态内容
Expires头
浏览器(或代理)使用缓存来减少HTTP请求的数量以及HTTP响应的大小,使Web页面加载更快
Web服务器使用Expires头来告诉Web客户端,可以使用一个组件的当前副本,直到指定的时间为止。
- HTTP 1.1 200 OK
- Content-Type: application/x-javascript
- Last-Modified: Wed, 22 Feb 2006 04;15;54 GMT
- Expires: Thu, 15 Apr 2010 20:00:00 GMT
当浏览器看到响应有一个Expires头时,它会将响应的过期时间和组件一起保存到其缓存中。只要组件没有过期,浏览器就会使用缓存版本而不会进行任何HTTP请求
Cache-Control
Expires存在一个限制: Expires头使用一个特定的时间,它要求服务器和客户端的时钟严格同步。另外,过期日期需要经常检查,并且一旦这一天到来,还需要在服务器配置中提供另一个日期
HTTP1.1引入了Cache-Control头使用max-age指定组件被缓存多久。如果从组件被请求开始过去的秒数少于max-age,浏览器就使用缓存的版本
- Expires: Thu, 15 Apr 2010 20:00:00 GMT
- Cache-Control: max-age=315360000
Cache-Control与Expires同时存在时,max-age指令将重写Expires头
Last-Modified
在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间
- Last-Modified: Fri, 12 May 2006 18:53:33 GMT
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过
- If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT
如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空
当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似
Etag
ETag是一个可以与Web资源关联的记号(token)。
典型的Web资源可以一个Web页,但也可能是JSON或XML文档。
服务器单独负责判断记号是什么及其含义,并在HTTP响应头
- ETag: "50b1c1d4f775c61:df3"
客户端的查询更新格式是这样的:
- If-None-Match: W/"50b1c1d4f775c61:df3 "
如果ETag没改变,则返回状态304然后不返回
利用Last-Modified和Etags提高性能
客户端通过将该标记传回服务器要求服务器验证其缓存有效性。其过程为:
- 1. 客户端请求一个页面(A)。
- 2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
- 3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
- 4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
- 5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。
组件更新
如果我们将组件配置为可以由浏览器代理缓存,当这些组件改变时用户如何获得更新呢?当出现了Expires 头时,直到过期日期为止一直会使用缓存的版本。浏览器不会检查任何更新,直到过了过期日期。因此,即使在服务器上更新了组件,已经询问过网站的用户也不大可能获取最新的组件(因为前一个版本已经在他们的缓存中了)。为了确保用户能在取组件的最新版本,需要在所有HTM 页面中修改组件的文件名。可以给组件文件名加入版本号
2.2 缓存DNS
通常浏览器通过DNS服务器解析一个域名花费时间20~120毫秒。在完成DNS解析之前,是不能够从服务器下载网页组件的。响应时间依赖于DNS解析器,它所承担的请求压力、与用户的距离以及网络带宽。
可以把 DNS查找的结果缓存起来提高性能,通常DNS缓存在ISP或局域网内特殊的服务器或独立用户的计算机上(主要关注点)。
未完待续...





