web服务器缓存(二)

来源:互联网 发布:centos 禁止ping 编辑:程序博客网 时间:2024/05/14 23:19

    通过(一),我们学会了配置Apache的cache模块,测试了静态文件的缓存,静态文件成功被web服务器“捕获”,生成了缓存文件,但是我们更关心的是动态文件,因为它比静态文件更加消耗服务器资源,如果能够对动态文件进行缓存,将会节省很大一笔开销,那么动态文件能否使用web服务器缓存呢?

    测试动态文件缓存

    如果读过小编的浏览器缓存相关文章的童鞋就会知道,web服务器在处理静态文件和动态文件的方式有所不同,那么动态文件能否正常的使用web服务器缓存呢?我们来测试下,输入一个动态网页的URL,然后查看缓存目录,果然,什么文件夹都没有生成,难道动态网页不能使用web服务器缓存?相信大家对这个疑问似曾相识,因为我们在学习动态文件的浏览器缓存的时候遇到了同样的问题,当时是手动添加了Last-Modified才出现了304,添加了Expires才出现了Cache,那么这些设置对于web服务器缓存有效果吗?既然有了方向,那么我们也同样添加Last-Modified来测试下吧。

<?php    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){        $modified_time = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);if($modified_time + 10 > time()){   header("HTTP/1.1 304 Not Modified");   exit(1);}    }    header("Last-Modified:".gmdate("D, d M Y H:i:s ")."GMT");    echo date('Y-m-d H:i:s');
    添加了Last-Modified相关代码之后,我们在访问下该URL,再次查看缓存目录,这次web服务器不在无动于衷,终于生成了我们梦寐以求的缓存。虽然添加Last-Modified能够使得动态文件产生缓存,但是我们可能对于文件在什么条件下才能被缓存仍然不是很清楚,下面我们就来看下被web服务器缓存的条件吧。

    什么条件才能被缓存?

    1.必须为该URL启用了缓存,还记得在Apache的配置文件中书写过“CacheEnable disk /”这样一个配置项吗,该语句就是为所有的URL启用了磁盘缓存,你也可以对URL进行设置,例如“CacheEnable disk http://www.xxx.com”,这样非该域名下URL将不会被缓存。

    2.应答必须具有如下HTTP状态码:200, 203, 300, 301, 410 。

    3.该请求必须是一个HTTP GET请求。

    4.如果URL包含了请求字符串,例如http://www.xxx.com/index.php?action=download,此时,除非设置了Expires头信息,否则将不被缓存。

    5.如果应答的状态码是200(OK),除非明确打开了CacheIgnoreNoLastMod指令(关于该指令这里不再详细介绍,有兴趣的朋友可以点击这里),否则该应答还必须至少包含一个"ETag"、"Last-Modified"或"Expires"头才能被缓存。

    动态文件缓存和静态文件缓存的区别

   web服务器会自动为静态文件添加缓存协商(Last-Modified和ETag),但不会为动态文件添加。根据上面描述的缓存条件来看,如果请求的URL启用了缓存,应答的状态码为200,则静态文件会直接被缓存(因为存在缓存协商),如果在没有打开CacheIgnoreNoLastMod指令的情况下,动态文件需要则需要手动添加缓存协商(Last-Modified或者ETag)或者过期时间(Expires,添加Cache-Control不行)。

    使用小结

    在对web服务器缓存的测试过程有很多心得体会,也遇到了很多的问题,有的问题解决了,有的问题没解决,现在列举出来供大家参考和讨论。

    1.web服务器缓存和浏览器缓存同时启用,动态文件在进行F5刷新(已对动态文件添加Last-Modified判断)的时候,不会返回304状态码(IE浏览器例外),仍然返回200。

    2.web服务器缓存产生了两个文件,.header和.data,一个存储HTTP头信息,一个存储响应内容。

    3.如果存在缓存协商(不管是否存在过期时间),.data在生成之后就不会改变,.header文件会随着每次请求而改变。如果访问的文件有所更改,只有在更改后的首次访问才能够获取最新内容,之后的访问仍然会访问.data中存储的缓存。.data里面的内容不会随之更新。

    4.如果仅使用过期时间(Expires),不使用缓存协商(这里指动态文件,因为静态文件web服务器会自动为其添加缓存协商),同样会生成.header和.data文件,与缓存协商生成的文件有所不同,这里的缓存文件存在以下几个过程,首次访问产生.header和.data文件,再次访问,删除.data文件,第三次访问删除.header文件,第四次访问再次生成了.header和.data文件,然后就是再次删除.data,再次删除.header,就这样依次循环。需要注意的是,不同浏览器不同的刷新方式产生的结果不同,google三种请求方式(超链接跳转方式除外)都会引起上述变化,火狐浏览器除了第三种请求方式,第一种和第二种都能够引起上述变化,而IE浏览器则只有第一种请求方式才能引起上述变化。

    5.如果不想添加缓存协商和过期时间,又想要动态文件被web服务器所缓存,可以添加在Apache的配置文件中为mod_cache添加CacheIgnoreNoLastMod On指令,这样使得web服务器同样能够缓存动态文件,效果跟仅使用过期时间(不使用缓存协商)一样。

    遗留问题

    问题一:虽然web服务器已经能够成功的缓存动态文件和静态文件,但是却出现了另一个难题,就是当缓存的内容改变的时候,如何及时更新响应内容?退一步讲,即使不能及时更新,那么如何定时更新内容?关于这个问题,小编测试了过期时间(Expires和Cache-Control),又测试了mod_cache模块缓存时间的相关的指令CacheDefaultExpire和CacheMaxExpire,没有一个能够达到小编预期的效果,不是不更新,就是不停的更新,翻看了很多资料,都没有就这个问题做出很好的说明,如果有对Apache的缓存模块mod_cache比较了解,能够解决小编这个疑问的,还望不吝赐教。

    问题二:在“使用小结”中第4和第5项虽然能够使得web服务器对动态文件进行缓存,但是每次访问缓存文件都在不停的变化,不停的删除,再次生成,跟问题一整好相反,问题一是响应内容一成不变,这里是瞬息万变,虽然能够及时获取到最新内容,但是总是这样不停的删除和生成,会不会对服务器造成更大的压力,这样做是否真的能够起到缓存的作用?虽然使用ab压测,效果还是很理想的(比不使用缓存提高20-30倍),但是它毕竟不是真实用户,模拟的访问与真实用户访问还是有所差别,此问题有待日后观察。

    注意事项

    1.如果手动为动态文件添加Last-Modified或者Expires的时候一定要注意日期的格式,多个空格,少个空格都会导致它们设置失效,如果设置了它们之后web服务器仍然无法缓存响应内容或者出现一些奇怪的问题,这时候就需要查看它们的日期格式是否设置正确。

    2.关于“什么条件才能被缓存”,这么并没有全部列举出来,如果对这些有兴趣的朋友可以点击这里,搜索“什么可以被缓存”。

    3.关于三种请求方式,可以参看小编的浏览器缓存中提到的如何请求页面。

0 0
原创粉丝点击