码迷,mamicode.com
首页 > Web开发 > 详细

Apache Httpd服务器之缓存粗解

时间:2015-06-01 20:54:40      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:web服务器缓存   apache缓存   apache服务器缓存   httpd缓存   静态缓存   动态缓存   

        当我们通过浏览器输入一个网址,然后服务器响应给我们内容时,服务器会有一个非常复杂的处理过程。服务器并不是每次都会根据我们请求的页面在磁盘上读取页面内容,然后将这些内容返回给浏览器供我们浏览。如果这样,那么当浏览器的并发请求特别多时,会对服务器造成很大的负载。那么服务器如何在并发请求特别大时还能保持响应水准呢?为了解决这一问题,http协议引进了缓存标准。而apache httpd服务器实现了http协议的这一标准。当然,请求和响应是双向的,所以缓存也不仅仅是在服务器这一端来实现,目前的主流浏览器也都实现了客户端缓存这一功能。这样一来,当浏览器输入网址时,如果服务器页面的内容没有更新,浏览器将立即把本地缓存的页面展示给用户浏览,根本就不用请求服务器。如果客户端缓存内容过期了,浏览器发送了一个请求给服务器,这时,服务器还可以进一步判断请求的页面内容是否有更改,如果没有更改,也不用进行磁盘操作去读取页面内容,而是直接返回一个特殊的状态码给客户端,客户端收到这个状态码后就直接取本地的缓存展现给用户浏览。所以,在一个请求过程中,客户端与服务器端都会对页面进行一系列的处理,为的就是减少请求量,减少数据传输量,达到降低服务器负载,加快响应速度的目的。

        在我们的请求中,有的请求是请求一个静态页面,比如输入http://ezmonitor.cn/wx1.jpg,这是一张静态的图片,请求100次还是显示同样的内容。这种请求我们自己发明个词,叫做“静态请求”。还有的请求是请求动态页面,比如输入http://ezmonitor.cn/dt.php?arg=123时,页面返回123,输入http://ezmonitor.cn/dt.php?arg=456时,页面返回456,虽然都是请求dt.php这个页面,但是参数不同的话,结果也不同,这种请求,我们又发明个词,叫做“动态请求”,在我们提到的客户端缓存中,只能缓存静态请求,而缓存不了动态请求。所以请求动态页面时,必然会产生一个请求链接,并且如果页面没有错误的话,必然会返回200代码,但是动态内容能不能缓存呢?答案是肯定的,但是它是缓存在磁盘上的,只能减少服务器处理代码的时间及减少I/O操作,并不能消除请求时间及数据量的传输。下面,我们就逐一来讨论下客户端缓存与服务器端缓存。

        客户端缓存

 技术分享

        技术分享


       浏览器第一次请求服务器时,http头的信息是这样的


       技术分享技术分享


       可以看到,没有什么特别的,只是一个普通的请求,只有一些简单的头信息,比如User-Agent,Accept-Encode: xxxx,Host: xxxx,而这些,都与我们今天要讨论的缓存无关,可以忽略。


技术分享技术分享


       服务器第一次返回给浏览器(以下简称为客户端),http头的信息是这样的,


      技术分享技术分享

     

        在服务器第一次返回的http头中,标记为红色箭头的地方是我们值得关注的。首先是ETag这个标记,ETag是服务器为客户端请求的文件计算的一个标记值,当请求的文件内容发生变化时,ETag也会发生变化。服务器在http响应中给出了ETag,那么客户端就将此ETag保存了起来。Cache-Control: max-age 这个标记是服务器缓存有效期时间,如果客户端在30秒内再次请求同一页面,服务器将使用缓存数据响应客户端(此值在静态请求中可能无效,因为有可能服务器根本就不需要取数据给客户端)。Expires这个标记表示客户端本地缓存的时间,在浏览器请求页面时,如果超过了此时间,那么浏览器就必须将此请求发送给服务器,否则浏览器将不产生请求并直接取本地的缓存数据。

        好了,接下来,我们进行第二次请求,此时,将可以看到缓存的处理机制。


技术分享技术分享


        第二次请求的方式有三种,

        第一种方式:以IE浏览器为例,如果在输入网址后点回车,这时,浏览器会检查上次服务器响应中传回的Expires标记,如果当前时间在Expires范围内,那么客户端将直接取本地缓存,不产生请求。如果你在win7下用IE操作,那么这个缓存文件的目录在C:\Users\Administrator\AppData\Local\Microsoft\Windows\Temporary Internet Files这里,在这里你可以找到index.html缓存文件。当Expires请求过期时,客户端将产生一个链接至服务器,请求的http头信息如下:

        技术分享技术分享



        这时,客户端将两个缓存相关的标记传给服务器,一个是If-Modified-Since,此标记的值是客户端本地缓存的上次修改时间,服务器接收到后将根据此时间与自己文件的修改时间进行比对,如果时间一致,将返回304代码告诉客户端直接取本地缓存。如果时间不一致,那么将返回200代码及新的内容给客户端,客户端将重新建立本地缓存。另外一个是If-None-Match,此标记的值告诉服务器上次接收到的Etag值,服务器接收后,会将此值与文件的最新的ETag值进行比较,如果一致,则返回304代码告诉客户端直接取本地缓存。如果时间不一致,那么将返回200代码及新的内容给客户端,客户端将重新建立本地缓存。此处,如果If-Modified-Since的值与服务器内文件的修改时间不一致,但ETag的值是一致的,那么服务器仍将返回304,这时,客户端依旧直接取本地缓存展现给用户。所以,在有ETag标记的情况下,服务器只会判断比较ETag的值。以下是第二次请求时,服务器的响应信息头:


    技术分享技术分享


        第二种方式:如果用户在输入网址后的,点击“刷新”,那么客户端将不判断Expires标记,而直接请求服务器。这时,服务器将会按照第一种方式来判断返回304或200。同样也是通过If-None-Match和If-Modified-Since标记值来判断。

        第三种方式:按Ctrl+F5强制刷新。这时,客户端请求的头信息如下:

技术分享技术分享

     

        可以看到,有个Cache-Control标记,它的值是no-cache,这时表明客户端要求服务器不使用缓存数据。所以此时,服务器返回客户端的代码必定为200,并且返回新的内容给客户端。此时,服务器端返回的http头信息为


技术分享技术分享

     

        可以看到,响应头信息依旧有相关的缓存标记。


       在httpd.conf中,我们可以设置客户端缓存的过期时间(也就是设置Expires标记的值)

     

     ExpiresActive on   #代表开启Expires设置
     ExpiresDefault "access plus 1 minute" #设置默认的Expires过期时间为1分钟
     ExpiresByType text/html "access plus 1 minute" #设置当请求text/html类型的资源时,过期时间为1分钟

       理解了以上的知识,其实配置就不是什么问题了。

      


        在客户端请求一个不存在的网页或请求一个错误页面时,客户端与服务端将不会建立缓存。客户端缓存就先介绍到这里,下面接着说说服务端缓存。

    

        服务端缓存

        服务端缓存建立在磁盘和内存上,它主要是在用户请求动态页面时,为用户省下代码逻辑处理的时间。同时,虽然服务器端缓存文件存储在磁盘上,当用户频繁的请求同一页面时,其实服务器也是通过内存直接将内容取出供用户浏览的。

        我们在httpd.conf配置文件内增加以下内容:

        CacheEnable disk /
        CacheRoot ‘/var/apache/cache‘
        CacheDirLevels 2
        CacheDirLength 1



        此配置是我们管理服务器上缓存文件的方案。CacheRoot表示缓存文件的根目录,所有的缓存文件都将在此目录下。CacheDirLevels为缓存文件根目录下的子目录深度,这里为2代表/var/apache/cache下有2级子目录。2级子目录下才是缓存文件。CacheDirLength代表缓存子目录名字长度,这里为1。所以我们的缓存子目录将有可能为/var/apache/cache/Y/e这样。那/var/apache/cache/Y/e这里面就是我们的缓存文件了。每一个类似/var/apache/cache/Y/e这种目录就对应一个URL的缓存文件,缓存文件的命名由22个字符组成,通常后缀为.data与.header,.data里存储的就是页面的内容,比如"hello world",.header里存储的为此url的请求头与响应头内容。当CacheDirLength为1时,将会生成64个子目录,当CacheDirLength为2时,那么每一层将可以生成64*64=4096个子目录,如果CacheDirLevels为2,CacheDirLength也为2, 那么将可以生成64*64*64*64=16777216个子目录。所以如果你没有那么多的url需要被缓存,还是将CacheDirLevels与CacheDirLength设置的小一些,以免对磁盘及I/O造成负载。

        下图就是服务器磁盘缓存的文件了

技术分享技术分享

       在设置磁盘缓存时,应格外注意,CacheRoot 对应的目录必须已存在,并且httpd服务器有可写的权限才行。


       服务器的缓存时间是通过Cache-Control标记里的max-age值来比较的,当客户端请求的间隔时间超过了上一次服务器返回头信息中的max-age值时,服务器将不会从缓存目录内取缓存内容给客户端。


        到这里,apache的缓存篇就告一段落了。在apache的配置中,还有一些其它的缓存相关设置,但是主要原理就是我以上说的这些。剩下的就靠大家慢慢去研究了。以上是我对于apache服务器缓存的一些理解,如果有说的不对的地方,也欢迎大家指正,共同进步。


本文出自 “架构师之路” 博客,请务必保留此出处http://wangweiak47.blog.51cto.com/2337362/1657139

Apache Httpd服务器之缓存粗解

标签:web服务器缓存   apache缓存   apache服务器缓存   httpd缓存   静态缓存   动态缓存   

原文地址:http://wangweiak47.blog.51cto.com/2337362/1657139

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!