加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 安全 > 正文

聊聊高并发系统之HTTP缓存

发布时间:2021-01-09 05:36:32 所属栏目:安全 来源:网络整理
导读:副标题#e# 《聊聊高并发系统之HTTP缓存》要点: 本文介绍了聊聊高并发系统之HTTP缓存,希望对您有用。如果有疑问,可以联系我们。 简介 最近遇到很多人来咨询我关于浏览器缓存的一些问题,而这些问题都是类似的,因此总结本文来解答以后遇到类似问题的朋友.

一般用于代理层(如CDN),用于代理层和浏览器协商什么情况下使用哪个版本的缓存内容(比如压缩版和非压缩版),即什么情况下后续请求才能使用代理层缓存的该版本内容,比如如下响应是告知浏览器Content-Encoding:gzip,即缓存代理层缓存了gzip版本的内容;那么后续的请求在请求时Accept-Encoding头部中包含gzip时才能使用改代理层缓存.

Via

一般用于代理层(如CDN),表示访问到最终内容经过了哪些代理层,用的什么协议,代理层是否缓存命中等等;通过它可以进行一些故障诊断.

ETag

@RequestMapping("/cache/etag")
public ResponseEntity<String> cache(
 ? ? ?HttpServletRequest request,? ? ?HttpServletResponse response,? ? ?//浏览器验证文档内容的实体 If-None-Match
 ? ? ?@RequestHeader (value = "If-None-Match",required = false) String ifNoneMatch) {

 ? ?//当前系统时间
 ? ?long now = System.currentTimeMillis();
 ? ?//文档可以在浏览器端/proxy上缓存多久
 ? ?long maxAge = 10;

 ? ?String body = "<a href=''>点击访问当前链接</a>";

 ? ?//弱实体
 ? ?String etag = "W/"" + md5(body) + """;

 ? ?if(StringUtils.equals(ifNoneMatch,etag)) {
 ? ? ? ?return new ResponseEntity<String>(HttpStatus.NOT_MODIFIED);
 ? ?}

 ? ?DateFormat gmtDateFormat = new SimpleDateFormat("EEE,Locale.US);
 ? ?MultiValueMap<String,String> headers = new HttpHeaders();

 ? ?//ETag http 1.1支持
 ? ?headers.add("ETag",etag); 
 ? ?//当前系统时间
 ? ?headers.add("Date",gmtDateFormat.format(new Date(now)));
 ? ?//文档生存时间 http 1.1支持
 ? ?headers.add("Cache-Control",HttpStatus.OK);
}

其中ETag用于发送到服务端进行内容变更验证的,而Catch-Control是用于控制缓存时间的(浏览器、代理层等).此处我们使用了弱实体W”343sda”,弱实体(”343sda”)只要内容语义没变即可,比如内容的gzip版和非gzip版可以使用弱实体验证;而强实体指字节必须完全一致(gzip和非gzip情况是不一样的),因此建议首先选择使用弱实体.nginx在生成etag时使用的算法是Last-Modified + Content-Length计算的:

ngx_sprintf(etag->value.data,”&;%xT-%xO&;”,

r->headers_out.last_modified_time,

r->headers_out.content_length_n)

到此简单的基于文档修改时间和过期时间的缓存控制就介绍完了,在内容型响应我们大多数根据内容的修改时间来进行缓存控制,ETag根据实际需求而定(比如).另外还可以使用html Meta标签控制浏览器缓存,但是对代理层缓存无效,因此不建议使用.

总结

1、服务端响应的Last-Modified会在下次请求时以If-Modified-Since请求头带到服务端进行文档是否修改的验证,如果没有修改则返回304,浏览器可以直接使用缓存内容;

2、Cache-Control:max-age和Expires用于决定浏览器端内容缓存多久,即多久过期,过期后则删除缓存重新从服务端获取最新的;另外可以用于from cache场景;

3、http/1.1规范定义的Cache-Control优先级高于http/1.0规范定义的Expires;

4、一般情况下Expires=当前系统时间 + 缓存时间(Cache-Control:max-age);

5、http/1.1规范定义了ETag来通过文档摘要的方式控制.

Last-Modified与ETag同时使用时,浏览器在验证时会同时发送If-Modified-Since和If-None-Match,按照http/1.1规范,如果同时使用If-Modified-Since和If-None-Match则服务端必须两个都验证通过后才能返回304;且nginx就是这样做的.因此实际使用时应该根据实际情况选择.还有If-Match和If-Unmodified-Since本文就不介绍了.

接下来我们看下如何使用nginx进行缓存控制.

nginx缓存设置

nginx提供了expires、etag、if-modified-since指令来进行浏览器缓存控制.

expires

假设我们使用nginx作为静态资源服务器,此时可以使用expires进行缓存控制.

location /img {

alias /export/img/;

expires 1d;

}

当我们访问静态资源时,如http://192.168.61.129/img/1.jpg,将得到类似如下的响应头:

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读