Cache友好型的url构造方法-林钰

来源:互联网 发布:直通车优化步骤 编辑:程序博客网 时间:2024/05/18 01:31

写这篇文章的目的:在日常的工作中,经常有同事来询问有关缓存的问题,例如这样的url会不会被缓存、缓存期多长等;另一方面,也在生产环境的Cache服务器上发现很多不可缓存的引用,既降低了Cache效率,又增加了服务器负担。所以,希望借此文把一些经验总结向大家分享一下,设计页面url的同学们如果可能的话,就可以在以后的工作中尽量避免出现自己攻击自家的Cache的情况。好了话不多说

1. 缓存的意义

首先老生常谈一下缓存的意义,不外乎:

1.1. 减少对网络带宽的占用

  • 如果大量文件缓存在网站外部的CDN节点,那么到我们网站服务器的文件请求就会少了,网站的带宽消耗就会减少;
  • 如果还有大量的文件是缓存在经常访问我们网站的用户的本地浏览器缓存目录,那么同理网站的带宽消耗会减少;

1.2. 提高访问速度,提升用户的体验

  • 如上所述,大量文件缓存在外部CDN节点,这些节点离用户比较近,相比到我们网站来网络时延就会小很多,用户访问页面的速度就会提高;
  • 再如上所述,缓存在用户本地浏览器缓存目录的文件是零时延的,根本不需要从网络上获得,可以想象对用户体验的改善有多大;

1.3. 减轻网站服务器的负担

  • 这个就不用解释了,到网站来的请求减少了,相应的服务器负担肯定是下降了;

几乎所有的大型网站都启用了CacheCDN来分担用户流量,腾讯和淘宝的CDN流量是以百G计的,不难想象假如没有CDN缓存,这些网站在数百G流量的压力下是什么样的情况。即使对B2B这样相对的网站来讲,静态文件的流量也有好几个G,做好文件缓存的规划对我们的意义也是非常重要的,从源头做起比积重难返时再改造来得有智慧。

OK意义谈完了,接下来步入正题。

2. 静态文件url应该长什么样

下面主要讲讲好的静态url设计应该是什么样的,哪些设计可能会造成Cache不友好。

  1. 长的过期时间

既然需要缓存,必然涉及缓存时间,所以HTTP header中应该有>30天的Expires/Cache-control头。有了这个过期头,缓存服务器、CDN才会缓存数据,否则只能靠配置默认规则了。You know,默认规则是考虑了大多数的妥协的结果,不是最好的结果。这一点大家可以去看新浪、搜狐、QQ、淘宝,他们的静态文件过期时间是在什么时候,可以告诉大家是在2012年到2021年之间。

设置方法很简单,在apache添加Expires模块就行了,手册网上很多。

  1. 避免更新

这里的更新指同名更新,有人可能会问,缓存的文件我要更新怎么办?这个问题与缓存本身是矛盾的,解决方法很简单:不更新。例如,`http://mat1.qq.com/js/speed_v1.9-min.js`是腾讯门户页面上的一个js,他们要更新这个js会怎么办呢,想必大家都看得明白不会去修改speed_v1.9-min.js这个文件,而是会生成speed_v2.0-min.js

避免同名更新,使文件版本化,这就是最佳答案。最近发现国际站的文件长过期版本化已经有很大进展了,例如`http://i00.i.aliimg.com/images/eng/style/icon/icon_atmonline_v2.gif`——相信下次修改会是v3.gif

  1. 避免随机数

经常变化的随机数是缓存的敌人,特别是每次请求都不一样的随机数。刚刚在缓存服务器上挖掘出一个这样的url,降低了命中率十几个百分点:`http://www.example.com/sfm/app/uploader_v2/uploader.swf?__updateTime1299549287375`,明显最后的字符串是与时间相关的随机数,每次用户访问,这个数都会不同(具体原因可参考哲学名言不可能两次踏进同一条河流),那么缓存就没有意义了:缓存的数据以后是没有第二次请求的,存了没用;要么不缓存?那就不必要通过缓存服务器了。

如果是类似这样的url`http://www.example.com/css/3v/component.css?t=070904.css` ,理论上讲这种是可以的,它可能是把这个css文件的修改时间作为一个参数放在末尾,除非下次修改否则数字永远不变。但是这种方法与动态脚本上传参数的方式无法区分,如果有动态脚本被缓存比如login的结果,阿猫会发现自己登到阿狗的帐户去了。所以万全之策是两种方法都不使用。

  1. 简短明了

大家可以参观一下这个url

      http://unic.alibaba.com/app/script_loader/script_loader|run/intl_searchweb/alitalk|lib/yui/connection/connection-min/

      |run/intl_searchweb/listSearchbar|run/intl_searchweb/list_page_select|run/intl_searchweb/yahoo_dms_create|r20101008|/

      app/p4p/express|app/p4p/express_next|app/p4p/express_prev|app/navigator/navigator|v214171345.js

没有耐性数数,复制下来wc了一下,328个字符。再对比一下刚才提到的腾讯`http://mat1.qq.com/js/speed_v1.9-min.js`40个字符。在这里不是对这个url进行批判,相信这么长有它的道理,只是用这个极端的例子说明一个对比,假设我们的网站有10000个并发(高峰期实际不止),不考虑请求的文件是什么,仅仅我们的请求本身消耗的带宽是328byte*10000*8bit/byte=26Mbps。如果同样缩减到40个字符,则带宽消耗就变成3Mbps了,差别还是有的,保证功能的前提下就短不就长。

  1. 避免cookie

现在咱们网站的cookie500-700字节,计算取平均值600byte,与上一条同理,用户请求我们的文件需要发送cookie10000的并发数,仅请求本身消耗带宽就是48Mbpscookie是页面必须的东西不能少,但是对于图片文件和css这类文件来讲,cookie就完全多余了,所以静态文件避免cookie既可以加快请求速度(不必send 600byte了),又可以减少服务器接收处理cookie的额外开销,何乐而不为呢?方法也很简单,把静态文件的域名改为无cookie的域就可以了。

  1. 域名数量

这一点来源是rfc规范里规定了浏览器在一次页面请求中,对同一个域名最多发起2个并发,顺理成章的,人们就想出了增加域名的方法来绕过这个限制。拆分域名这一条在以前浏览器仅支持一个域名两个并发的年代是比较重要的,可以增加文件下载的并发数,提高页面load速度。但是现在的IE8FF3等浏览器都支持超过2个的并发,FF36个并发,IE8甚至能够支持到18个并发,以增加并发为目的的诉求并不是那么大了。

另一方面,拆分域名和控制域名数量是一个平衡的过程,页面上域名的数量不能太多,否则花在DNS解析上的时间也不少,雅虎牛人出的著名网站优化“14中说静态域名不要超过4个,就是从DNS解析效率方面出发的。其实在浏览可以支持大并发的前提下,这一点已经不太重要,建议结合上面提到的避免cookie”的那条规则,酌情定数量。

3. 总结

不知不觉列了这么多,基本上都是平时工作中遇到的问题的总结,共享给大家作为参考。上面提到的很多东西都要倚仗咱们的开发、ued工程师来完成,这里只是结合了通行的优化做法和网站实际情况提供了一些建议,期望在以后新建站点、开发新业务时可以避免历史的错误。共同将网站速度优化这件事情做好。

原创粉丝点击