经过大量不成功的研究后,我想知道是否可以使用nginx或varnish cache函数来检查标题中包含etag属性所包含的数据新鲜度。
使用图表更容易解释这种情况,请参阅下文:
http://image.noelshack.com/fichiers/2014/49/1417684577-cache-nginx.png
您认为此用例是否可行?
谢谢你,对不起我的英文:s
答案 0 :(得分:0)
您可以使用清漆stale-while-revalidate执行类似操作,但不完全相同。使用前端缓存的想法是,当后端将对象发送到缓存时,它会设置一个Expires头,该头将允许缓存提供此内容而不会打扰后端。如果缓存会使用后端检查每个请求,那么获得的速度就不会太快,因为您最终会等待每个请求的后端。
要解决此问题,您应该相应地设置Expires标头,并且/或者如果突然您需要在Expires之前删除陈旧内容,则清除/禁止URL。这样缓存就会从自己的缓存中发送内容,或者如果没有它或者它已经过时,则从后端获取内容。
编辑:
我已经使用Varnish 4.0.1进行了测试,它支持对后端的条件请求。
我的测试设置是带有ExpiresByType text/html "access plus 5 seconds"
结果:
* << BeReq >> 65539
- Begin bereq 65538 bgfetch
- Timestamp Start: 1418403624.141695 0.000000 0.000000
- BereqMethod GET
- BereqURL /prueba.html
- BereqProtocol HTTP/1.1
- BereqHeader User-Agent: lwp-request/6.03 libwww-perl/6.05
- BereqHeader X-Forwarded-For: 127.0.0.1
- BereqHeader Host: localtest
- BereqHeader Surrogate-Capability: key=ESI/1.0
- BereqHeader Accept-Encoding: gzip
- BereqHeader If-Modified-Since: Thu, 01 Dec 2011 10:37:55 GMT
- BereqHeader If-None-Match: "3e8be5-46-4b30571f606c0"
- BereqHeader X-Varnish: 65539
- VCL_call BACKEND_FETCH
- VCL_return fetch
- Backend 17 vdir server1(127.0.0.1,,80)
- Timestamp Bereq: 1418403624.141869 0.000174 0.000174
- Timestamp Beresp: 1418403624.143205 0.001510 0.001336
- BerespProtocol HTTP/1.1
- BerespStatus 304
- BerespReason Not Modified
- BerespHeader Date: Fri, 12 Dec 2014 17:00:24 GMT
- BerespHeader Server: Apache
- BerespHeader ETag: "3e8be5-46-4b30571f606c0"
- BerespHeader Expires: Fri, 12 Dec 2014 17:00:29 GMT
- BerespHeader Cache-Control: max-age=5
- TTL RFC 5 -1 -1 1418403624 1418403624 1418403624 1418403629 5
- BerespProtocol HTTP/1.1
- BerespStatus 200
- BerespReason OK
- BerespHeader Last-Modified: Thu, 01 Dec 2011 10:37:55 GMT
- BerespHeader Content-Type: text/html
- VCL_call BACKEND_RESPONSE
- TTL VCL 5 21600 0 1418403624
- VCL_return deliver
- Storage malloc s0
- ObjProtocol HTTP/1.1
- ObjStatus 200
- ObjReason OK
- ObjHeader Date: Fri, 12 Dec 2014 17:00:24 GMT
- ObjHeader Server: Apache
- ObjHeader ETag: "3e8be5-46-4b30571f606c0"
- ObjHeader Expires: Fri, 12 Dec 2014 17:00:29 GMT
- ObjHeader Cache-Control: max-age=5
- ObjHeader Last-Modified: Thu, 01 Dec 2011 10:37:55 GMT
- ObjHeader Content-Type: text/html
- BackendReuse 17 server1(127.0.0.1,,80)
- Timestamp BerespBody: 1418403624.143465 0.001770 0.000260
- Length 70
- BereqAcct 289 0 289 181 0 181
- End
在这里你可以看到我要求一个过时的对象,所以清漆去获取它,并以这种方式请求它:
- BereqURL /prueba.html
- BereqHeader If-Modified-Since: Thu, 01 Dec 2011 10:37:55 GMT
- BereqHeader If-None-Match: "3e8be5-46-4b30571f606c0"
后端回答:
- BerespStatus 304
- BerespReason Not Modified
- BerespHeader Date: Fri, 12 Dec 2014 17:00:24 GMT
- BerespHeader ETag: "3e8be5-46-4b30571f606c0"
- BerespHeader Expires: Fri, 12 Dec 2014 17:00:29 GMT
- BerespHeader Cache-Control: max-age=5
因此没有传输正文字节,而varnish使用新更新的标题刷新它的对象。
也许这就是你想要的行为。
请注意,确认条件(GET
和If-Modified-Since
)的If-None-Match
请求只会返回304 Not Modified
,某些标题和正文(完全是就好像它是具有相同条件的HEAD
请求一样),如果它没有验证它将返回标题和新主体。但是,未验证的HEAD
个请求会返回200 OK
和 NO 正文,强制您使用GET重新请求它。
HTTP/1.1 Method Definitions RFC:
HEAD方法与GET相同,只是服务器不能在响应中返回消息体。元信息 包含在HTTP头中以响应HEAD请求应该是 与响应GET请求时发送的信息相同。