首页 > LNMP应用服务器 > Expires与ETag

Expires与ETag

2015年11月10日

Expires与ETag

http://blog.itpub.net/27043155/viewspace-733095/

.Blog_nav1_2 a em { display:inline-block; width:16px; height:13px; background:url(/image/v.jpg) no-repeat; overflow:hidden;} Expires与ETag-nginx_web-ITPUB博客

在Nginx中没有使用Etag头,安装Nginx的创始人Igor Sysoev的观点“对于静态资源而已,看不出Etag比Last-Modified好”,因此在Nginx中就没有用Etag。但是Etag也有自己的独到之处,它可以解决Last-Modified无法解决的问题Etag。

 

按照业界的分析有三种情况:

 

下面是文件属性的状态参数

[[email protected] ~]# stat README

File: `README’

Size: 2075           Blocks: 16         IO Block: 4096   regular file

Device: fd00h/64768d   Inode: 15466845   Links: 1

Access: (0644/-rw-r–r–) Uid: (   0/   root)   Gid: (   0/   root)

Access: 2011-07-28 21:05:00.000000000 +0800

Modify: 2011-07-28 21:05:00.000000000 +0800

Change: 2011-11-11 11:27:18.000000000 +0800

 

  • 对于修改非常频繁的文件,可能会在1秒内修改多次,由于Last-Modified是基于秒级检测的,说到根源是由于它检测的依据是被访问文件修改时间的Linux系统的时间戳,因此在秒内修改的情况下是Last-Modified无法检测出的。对于这种情况,我认为就没有没有启用缓存了。

 

  • 对于周期性改变的文件,这种情况很常见,通常文件内容并没有发生改变而只是文件的Modify的改变,如果想测试这种情况,可也使用touch命令来touch一个已经存在的文件来测试。文件的内容并未改变,但是依据Last-Modified的原理需要重新获取。

 

  • 有些无法精确到文件的最后修改时间,这种情况不是很多。

 

这两个Http头都是用于有效控制客户端缓存的,在Nginx中可也通过以下配置指令来实现:

 

location / {

root   html;

index index.html index.htm;

expires 10d;

FileETag on;

}

 

第一次访问该目录下的网页时响应头如下:

 

 

 

再次访问的请求头和响应头如下:

 

 

 

再次访问的请求头和响应头如下:

 

 

 

分析这三次访问,以Expires为缓存的方式是使用了时间缓存,即按照RFC2616对HTTP协议的规定,在客户端第二次向服务器发出请求时,对于第一次访问请求的资源如果响应状态为200的资源,那么在这次请求中将会添加一个新的请求头:If-Modified-Since,故名思议,就是询问服务器从这个时间起,或者说是以这个时间为分割点,在这时间点之前有没有修改过这个文档,如果没有修改,那么发挥的http状态代码是304.并且同时再次发回响应头Last-Modified,注意这两个头的时间完全相同。

 

这就是Expires的原理。

 

而Etag的工作原理则与Expires完全不同,按照HTTP协议的规定,对于Etag的值么有过的的规定,而只是规定了要将Etag的值放置在一对引号(””)之内。因此在开发上就灵活了很多。在后面会讲到Nginx的第三方模块nginx-static-etags模块来实现对静态文件提供Etag。

 

它的原理就是通过检查这个一对引号(””)之内的值,或者是说有引号之内定义的值(就是说由变量生成的值,例如URI、文件大小等等,这由具体的开发来决定,如果你对开发感兴趣,那么可以查看nginx-static-etags的源代码,另外,如果需要自己设置If-None-Match匹配的值,就是说在nginx-static-etags模块中由etag_format指令产生的格式,那么也可以使用Nginx提供的变量来实现)。

 

Etag的检测是使用了If-None-Match头,在客户端第一次访问一个页面时,在服务器的响应头中会发送回一个叫做Etag的响应头,在前面的截图中我们也看到过,在第二次对同一个页面发出请求是在请求头中会有一个If-None-Match头,如果与服务器端再次生成的Etag匹配,那么表示请求的页面并没有改变,而是以304代码响应,同时再响应头中再次发回If-None-Match头。

 

这里就需要说一点,使用了Etag是有代价的(无论多少总是有的),它有个产生Etag和比较Etag的过程,因此会占用CPU资源。

 

最后一个点需要说的是,在我们同时使用了Expires和Etag之后,没有谁优先的问题,而是满足两者才会做出决定。

分类: LNMP应用服务器 标签:
本文的评论功能被关闭了.