首先我画了一个粗糙的图形,用来表示我们使用web请求所经历的过程。大家将就看下
从图可以看出,当用户发起一个网络请求。首先会经过浏览器的缓存,然后经过静态资源的CDN缓存,然后是Nginx等反向代理缓存,再是web缓存,最后还有数据库缓存。下面我们一一来看。
http协议有自己的缓存协商机制。
对于http1.0 使用的是基于iso-time的 expired响应头去判断资源过期与否。
http1.1使用三种
1.是基于修改精确时间的Last-Modifie(在这个时间点的之后的我才去请求新数据)
2基于文件相对时间的max-age(这个资源你可以用多久)
from cache 是没有和服务器确认,一般是运维去除了e-tag或者说是使用了长缓存
3.基于文件内容hash的 e-tag(e-tag变化才请求新数据)
CND是为了不同的网络环境都可以获得一致的高速体验而服务的。将一些静态资源放在cdn可以使用户访问这个静态资源的时候选择网络状态最好的。合理使用cdn可以大大提高访问速度。但是cdn也有很麻烦的地方,就是发布的时候,浏览器缓存可能读取的是旧版本的,这时候传统方法是使用query,但是query也有很多问题,文件发布顺序啥的会影响,而且需要手工加入版本号。 这里推荐webpack build 加hash
这里说的是反向代理(我觉得叫服务端代理可能更容易理解)反向代理有保护服务器安全(将外部请求转发给内部服务器,同时将内部服务器响应转发给Client),缓存加速和实现负载均衡的作用。现在我们的站点测试环境使用的是Nginx1.8.x 。而生产环境使用的是淘宝Tengineer
我们系统使用的tomcat服务器,所以在这里讲一下tomcat服务器的缓存策略。
tomcat默认是只对静态组员进行缓存对jsp是不缓存的。当前端发送一个请求时,服务端会根据这个资源的特征进行不同的缓存策略。 本质上是存到一个map中,将etag或者last-modified作为value(前面讲浏览器缓存有说过),将资源的url作为一个key存储,当资源发生变化的时候我们去更新这个map的value,当下次资源被请求会比较etag或者last-modified是不是最新的数据,如果是返回304.不是的话返回200和对应内容
tomcat源码中的!checkIfHeaders(request, response, cacheEntry.attributes)) 是整个机制的核心,用来判断资源是否需要重新获取,返回false就重新获取
protected boolean checkIfHeaders(HttpServletRequest request,
HttpServletResponse response,
ResourceAttributes resourceAttributes)
throws IOException {
return checkIfMatch(request, response, resourceAttributes)
&& checkIfModifiedSince(request, response, resourceAttributes)
&& checkIfNoneMatch(request, response, resourceAttributes)
&& checkIfUnmodifiedSince(request, response, resourceAttributes);
}
这里四个check都返回true(都认为资源被改变了),那么checkIfHeaders久返回true,对应就要重新获取而不走缓存
在这里使用memcached大大缓解了数据库的读压力,当然对于写还是会造成负担的(更新数据, 需要同时更新数据库和缓存),好在大部分应用都是读远大于写,使用simple spring memcached大大简化了缓存配置,ssm在key生成规则和list缓存上做的很好。有时间我也会进一步了解下。
环境:reflux + react
首先将cache挂载到store上,然后get之前判断缓存中有没有,如果有直接返回否则发送一个请求
然后请求成功,如果缓存不存在则添加缓存
直接在请求成功后更新对应缓存。
可以看下效果
博客不可以上传视频,悲哀啊。那就图片吧。
每次请求都是6个,切换三次页面就有18次请求,再切换会更多。时间大家可以自己算下
看下优化后的结果:
只有第一次请求会加载6次以后都是不会请求的