<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Heck's  Blog]]></title> 
<link>https://www.heckjj.com/index.php</link> 
<description><![CDATA[一瞬间的决定，往往可以改变很多，事实上，让自己成功的往往不是知识，是精神！ 如果你总是为自己找借口，那只好让成功推迟。执行力，今天！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Heck's  Blog]]></copyright>
<item>
<link>https://www.heckjj.com/post//</link>
<title><![CDATA[ETAG的工作原理]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[Web开发]]></category>
<pubDate>Tue, 18 Jul 2017 07:28:14 +0000</pubDate> 
<guid>https://www.heckjj.com/post//</guid> 
<description>
<![CDATA[ 
	<p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">转来的一篇博文，此文详细说明了ETAG的作用。我发现网上很多人都在询问ETAG的对于优化网站的作用，有些人直接建议关闭ETAG。这篇博文可以完整的说明ETAG的作用，是否关闭，或者如何配置，要根据自己网站的情况而定。</p><h2 style="margin: 0.83em 0px; padding: 4px; font-size: 22px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; line-height: 28px">开始ETAG测试</h2><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">首先在浏览器输入以下访问地址<br />比如我们访问某网站：http://xxxxxxxx/<br />第一次的http请求代码如下（只包含头部信息）<br />&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-<br />CODE:<br />GET / HTTP/1.1<br />Host: xxxxxxxx<br />User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; ja; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3<br />Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5<br />Accept-Language: ja,en-us;q=0.7,en;q=0.3<br />Accept-Encoding: gzip,deflate<br />Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7<br />Keep-Alive: 300<br />Connection: keep-alive</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">服务器的返回http头部内容：<br />&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-<br />CODE:<br />HTTP/1.x 200 OK<br />Date: Mon, 07 May 2011 11:49:33 GMT<br />Server: Apache/2.2.4 (Unix)<br />Last-Modified: Sat, 20 Nov 2009 20:16:24 GMT<br />Etag: &ldquo;4c602bd-2c-4c23b600&Prime;<br />Accept-Ranges: bytes<br />Content-Length: 44<br />Connection: close<br />Content-Type: text/html</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">再次refresh，重新访问http://xxxxxxxx/</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-<br />第二次的请求http头内容如下<br />&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-<br />CODE:<br />GET / HTTP/1.1<br />Host: xxxxxxxx<br />User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; ja; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3<br />Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5<br />Accept-Language: ja,en-us;q=0.7,en;q=0.3<br />Accept-Encoding: gzip,deflate<br />Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7<br />Keep-Alive: 300<br />Connection: keep-alive<br />If-Modified-Since: Sat, 20 Nov 2004 20:16:24 GMT<br />If-None-Match: &quot;4c602bd-2c-4c23b600&quot;<br />Cache-Control: max-age=0</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-<br />此时的http响应头如下<br />&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-<br />CODE:<br />HTTP/1.x 304 Not Modified<br />Date: Mon, 07 May 2011 11:51:27 GMT<br />Server: Apache/2.2.4 (Unix)<br />Connection: close<br />Etag: &ldquo;4c602bd-2c-4c23b600&Prime;</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">以上的交互过程中有几个头部信息特别需要关注：</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">１）初次的http请求信息，收到的返回信息里面有个Etag标志</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">CODE:</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">Etag: &ldquo;4c602bd-2c-4c23b600&Prime;</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">２）第二次请求的http信息</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">CODE:</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">If-None-Match: &ldquo;4c602bd-2c-4c23b600&Prime;</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">３）第二次访问的响应http信息</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">CODE:</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">HTTP/1.x 304 Not Modified</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">Etag: &ldquo;4c602bd-2c-4c23b600&Prime;</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px"> </p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px"> </p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">ETag被用在为了节省网络带宽进行缓存判断的机制上，Apache默认采用文件的inode，size，最终修改时间(mtime来生成Etag)。Apache允许关闭Etag功能，只要配置FileETag None 即可。</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">也就是说对Apache 请求静态内容（html网页、图片、css、javascript文件等）时候，Apache会按照请求文件的inode，大小，以及最终的修改时间来生成Etag的内容，并且包含在http的响应头部信息返回给客户端。</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">当浏览器访问网页的时候，会在http请求头中加入If-None-Match头部信息（前提是前次请求时服务器返回了Etag头部信息），内容是以前服务器发送回来的Etag信息。Apache收到该请求后，比较接收到的Etag和自己再次计算出的etag内容，如果两者相等，则返回&ldquo;<span style="color: #ff00ff"><span style="font-weight: 700">304 Not Modified</span></span>&rdquo;，如果不相等，则返回 200 OK和实际请求的内容。</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">注意这个时候If-None-Match相比于If-Modified-Since具有更高的优先级别。</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">如果ETag被关闭，服务器将使用If-Modified-Since参数来判断页面是否有更新，浏览器的If-Modified-Since参数来自原服务器上一次响应报文中的Last-Modified参数，这个参数精确到秒，也就是说，如果出现1秒内页面被多次修改，使用这个参数就无法判断，这就是要增加ETag的原因。</p><h2 style="margin: 0.83em 0px; padding: 4px; font-size: 22px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; line-height: 28px">多台服务器负载均衡的情况</h2><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">在web服务器只有一台的情况，请求内容的唯一性可以由Etag来确定，但是如果是多台web服务器在负载均衡设备下提供对外服务，尽管各web服务器上的组件内容完全一致，但是由于在不同的服务器上inode是不同的，因此对应生成的Etag也是不一样的。在这种情况下，尽管请求的是同一个未发生变化的组件，但是由于Etag的不同，导致Apache服务器不再返回「&ldquo;<span style="color: #ff00ff"><span style="font-weight: 700">304 Not Modified</span></span>&rdquo;，而是返回了200 OK和实际的组件内容（尽管事实上内容不曾发生变化），大大浪费了带宽。</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">例如：一个在load balancer（负载平衡）下的web服务器群，同一浏览器来的多次访问被轮询分配到不同的服务器上，因此每次都得到不同的Etag，从而导致客户端每次都要从服务器端接收原本已经在客户端缓存的内容，徒然浪费了服务器端宝贵的带宽资源。</p><h2 style="margin: 0.83em 0px; padding: 4px; font-size: 22px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; line-height: 28px">一些解决办法</h2><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">Etag的生成因素限制为：Inode，文件大小和最后修改时间 (mtime)</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">CODE:<br /><span style="color: #0000ff">FileETag INode MTime Size<br />或者：FileETag All</span></p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">不让服务器返回ETag（从而浏览器再次发送http请求时候不再捎带If-None-Match）</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">CODE:<br /><span style="color: #0000ff">FileETag None</span></p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">这个配置可以加在网站顶级目录的.htaccess文件中，如果使用VPS，或者<a style="text-decoration: none; color: #336699" href="http://www.maixj.net/tag/aliyun" target="_blank">阿里云主机</a>这样的云服务器，也可以直接在httpd.conf文件中增加，后者更好。</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">如上修改后我们再次观察服务器的返回的http头部情况，可以发现返回的http头部信息里面不再含有ETag信息了：</p><p style="margin: 1em 0px; text-indent: 32px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; font-size: club.html; line-height: 28px">CODE:<br />HTTP/1.x 200 OK<br />Date: Tue, 08 May 2011 06:39:22 GMT<br />Server: Apache/2.2.4 (Unix)<br />Last-Modified: Sat, 20 Nov 2009 20:16:24 GMT<br />Accept-Ranges: bytes<br />Content-Length: 44<br />Connection: close<br />Content-Type: text/html</p>
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post//#blogcomment</link>
<title><![CDATA[[评论] ETAG的工作原理]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>https://www.heckjj.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>