Etag

Etag


1、浏览器第一次请求图片资源文件,服务端计算出etag标识,并通过响应头告诉浏览器,如标红部分

  1. Remote Address:
    10.70.128.75:8080
  2. Request URL:
    http://wap.cmread.com/r/cover_file/8231/392268231/20140212102919/cover75100.jpg
  3. Request Method:
    GET
  4. Status Code:
    200 OK
  5. Request Headersview parsed
    1. GET http://wap.cmread.com/r/cover_file/8231/392268231/20140212102919/cover75100.jpg HTTP/1.1 Host: wap.cmread.com Proxy-Connection: keep-alive Cache-Control: no-cache Accept: image/webp,*/*;q=0.8 Pragma: no-cache User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.132 Safari/537.36 Referer: http://wap.cmread.com/r/392268231/index.htm?nid=394224146&page=1&purl=%2Fr%2Fp%2Findex.jsp&srsc=1&vt=2&f=100557&pg=11&fraSeq=55&dataSrcId=22377209&sqId=L1 Accept-Encoding: gzip,deflate,sdch Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 Cookie: JSESSIONID=91F9B74DEA37D0B23DC8F5919D3476EE; cookies_user_home_page=/r/p/index.jsp; cookies_user_wap_version=2; userVistorId=90458599284; cookies_user_wap_version=2; userPhone=18857188505
  6. Response Headersview parsed
    1. HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Accept-Ranges: bytesETag: W/"3817-1392213349000"Last-Modified: Wed, 12 Feb 2014 13:55:49 GMT Content-Type: image/jpeg;charset=UTF-8 Date: Tue, 03 Jun 2014 02:04:33 GMT Content-Length: 3817 Proxy-Connection: Keep-Alive Connection: Keep-Alive Age: 0

2、浏览器第二次请求图片资源文件,浏览器会将之前拿到的etag标识增加到请求头的if-none-match中,

      服务端解析到文件字段,则会取文件当前etag与请求头中的if-none-match内容进行对比,如果一致,则反馈304 not modified


  1. Remote Address:
    10.70.128.75:8080
  2. Request URL:
    http://wap.cmread.com/r/cover_file/8231/392268231/20140212102919/cover75100.jpg
  3. Request Method:
    GET
  4. Status Code:
    304 Not Modified
  5. Request Headersview source
    1. Accept:
      image/webp,*/*;q=0.8
    2. Accept-Encoding:
      gzip,deflate,sdch
    3. Accept-Language:
      zh-CN,zh;q=0.8,en;q=0.6
    4. Cache-Control:
      max-age=0
    5. Cookie:
      JSESSIONID=91F9B74DEA37D0B23DC8F5919D3476EE; cookies_user_home_page=/r/p/index.jsp; cookies_user_wap_version=2; userVistorId=90458599284; cookies_user_wap_version=2; userPhone=18857188505
    6. Host:
      wap.cmread.com
    7. If-Modified-Since:
      Wed, 12 Feb 2014 13:55:49 GMT
    8. If-None-Match:
      W/"3817-1392213349000"
    9. Pragma:
      no-cache
    10. Proxy-Connection:
      keep-alive
    11. Referer:
      http://wap.cmread.com/r/392268231/index.htm?nid=394224146&page=1&purl=%2Fr%2Fp%2Findex.jsp&srsc=1&vt=2&f=100557&pg=11&fraSeq=55&dataSrcId=22377209&sqId=L1
    12. User-Agent:
      Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.132 Safari/537.36
  6. Response Headersview source
    1. Accept-Ranges:
      bytes
    2. Age:
      0
    3. Connection:
      Keep-Alive
    4. Content-Type:
      image/jpeg;charset=UTF-8
    5. Date:
      Tue, 03 Jun 2014 02:14:58 GMT
    6. ETag:
      W/"3817-1392213349000"
    7. Last-Modified:
      Wed, 12 Feb 2014 13:55:49 GMT
    8. Proxy-Connection:
      Keep-Alive
    9. Server:
      Apache-Coyote/1.1


3、关于集群业务到底是否适合使用etag

      之前网上主流说法是采用集群方式部署的业务不适合用etag来进行缓存,原因是etag会根据inode进行计算,导致不同主机计算出来的etag可能不同。

      针对这个问题,我在内网进行验证发现不同主机(跨机房)对同一图片资源生成的Etag是完全相同的,与网上的说法并不一至。

      分析apache-tomcat-7.0.54源码发现,etag的计算方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apache-tomcat-7.0.54-src/java/org/apache/naming/resources/ResourceAttributes.java
 
    /**
     * Get ETag.
     
     * @return strong ETag if available, else weak ETag. 
     */
    public String getETag() {
        String result = null;
        if (attributes != null) {
            Attribute attribute = attributes.get(ETAG);
            if (attribute != null) {
                try {
                    result = attribute.get().toString();
                catch (NamingException e) {
                    // No value for the attribute
                }
            }
        }
        if (result == null) {
            if (strongETag != null) {
                // The strong ETag must always be calculated by the resources
                result = strongETag;
            else {
                // The weakETag is contentLength + lastModified
                if (weakETag == null) {
                    long contentLength = getContentLength();
                    long lastModified = getLastModified();
                    if ((contentLength >= 0) || (lastModified >= 0)) {
                        weakETag = "W/"" + contentLength + "-" +
                                   lastModified + """;
                    }
                }
                result = weakETag;
            }
        
        return result;
    }


    可以看出,etag仅根据contentLength和lastModified进行计算,并没有使用到文件inode,所以对于同一个文件只要文件大小 和最后修改时间完全一致,则在不同的主机上计算出来的etag是完全一致的。






原文地址:https://www.cnblogs.com/zhangbo2012/p/38998c2537a14f420000000000000000.html