1、浏览器第一次请求图片资源文件,服务端计算出etag标识,并通过响应头告诉浏览器,如标红部分
- Remote Address:10.70.128.75:8080
- Request URL:http://wap.cmread.com/r/cover_file/8231/392268231/20140212102919/cover75100.jpg
- Request Method:GET
- Status Code:200 OK
- 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
- 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
- Remote Address:10.70.128.75:8080
- Request URL:http://wap.cmread.com/r/cover_file/8231/392268231/20140212102919/cover75100.jpg
- Request Method:GET
- Status Code:304 Not Modified
- Accept:image/webp,*/*;q=0.8
- Accept-Encoding:gzip,deflate,sdch
- Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
- Cache-Control:max-age=0
- 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
- Host:wap.cmread.com
- If-Modified-Since:Wed, 12 Feb 2014 13:55:49 GMT
- If-None-Match:W/"3817-1392213349000"
- Pragma:no-cache
- Proxy-Connection:keep-alive
- 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
- User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.132 Safari/537.36
- Accept-Ranges:bytes
- Age:0
- Connection:Keep-Alive
- Content-Type:image/jpeg;charset=UTF-8
- Date:Tue, 03 Jun 2014 02:14:58 GMT
- ETag:W/"3817-1392213349000"
- Last-Modified:Wed, 12 Feb 2014 13:55:49 GMT
- Proxy-Connection:Keep-Alive
- 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是完全一致的。