缓存策略汇总
上一篇 <<<动静分离架构模式
下一篇 >>>后端服务的雪崩效应及解决思路
1.浏览器缓存
浏览器自带缓存304:图片的默认缓存时间为7天
客户端(浏览器)发送请求到服务器端 第一次请求的时候会缓存所有的静态资源到浏览器;
客户端发送第二次请求的时候 如果本地浏览器有缓存,就使用本地浏览器的;
Key:访问的url
value:具体的值信息
原理:
a、第一次下载资源的时候,客户端会保存修改时间
b、第二次下载资源的时候,客户端上传修改时间,服务端决定返回200还304.
----这种时间不一定准,所以请求的时候一般会加上一个时间戳或版本号信息强制刷新。http://www.baidu.com?v=20200202
动态资源:
需要手动在响应头里加上最后修改时间,默认不会自动缓存
2.Nginx静态页面缓存
配置nginx的缓存策略,含名称、存放位置、存放大小限制、有效期和状态信息,其中key为url信息。
如果url不变,就算上游服务器挂了,也能从nginx中直接获取。缺点是上游服务器变了,由于url没变,缓存数据无法刷新。所以解决nginx缓存刷新的关键在于url的变更,可以加上时间戳。
# 代理缓存配置
proxy_cache_path "./meite_cachedata" levels=1:2 keys_zone=meitecache:256m inactive=1d max_size=1000g;
server {
listen 80;
server_name localhost;
location /details {
#使用缓存名称
proxy_cache meitecache;
#对以下状态码实现缓存
proxy_cache_valid 200 206 304 301 302 1d;
#缓存的key
proxy_cache_key $request_uri;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
location /all {
proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
}
3.CDN内容分发缓存
CDN的全称是Content Delivery Network,即内容分发网络,是一组分布在多个不同地理位置的Web服务器,目的是使用户能就近地获取请求数据,解决网络拥塞,提高访问速度,解决由于网络带宽小、用户访问量大、网点分布不均等原因导致的访问速度慢的问题。CDN能够缓存JavaScript脚本、CSS样式表、图片、图标、Flash等静态资源文件(不包括html页面),这些静态资源文文件的访问频率很高,将其缓存在CDN可以极大地提高网站的访问速度。
原理:能够将静态资源缓存到全国各地节点能够减少客户端与cdn带宽距离传输提高响应速度; 就近原则
为什么将静态资源存放到第三方服务器效率非常高呢?
1M公网带宽的理论下载速度是128k/s,一张图如果2M,则需要16s,如果并发量很高,则速度会非常的慢,而且非常的占用带宽,而且还和传输的距离有关系。
如果图片过大的情况下,建议将一张大图拆分n多个小图加载;
为了解决以上问题,可以使用第三方服务器,因为
1、云服务器签订带宽都是将T算的,价格更便宜
2、CDN内容分发,能够将静态资源缓存到全国各地节点能够减少客户端与cdn带宽距离传输提高响应速度; 就近原则。
传统方式架构弊端?
a.带宽传输压力大
b.因为所有用户全部聚集到同一个地区服务器上访问,无法保证整体的系统高可用
c.因为如果客户端与服务器端传输距离越远,那么宽带传输非常耗资源,导致用户体验非常差,响应慢。
CDN安全控制或还提供了其他什么服务?
防止DDOS攻击、DNS负载均衡、实现WEB安全防御功能,比如黑名单和白名单
4.服务端SpringBoot整合Redis缓存
a、启动的配置文件上加上注解@EnableCaching
b、使用的地方加上注解
@Cacheable(cacheNames = "case",key = "'caseDetail'")
cachenames相当于文件夹,后面的key为具体的key,key一定要加上单引号,不加会报错
缓存的内容必须要实现序列化
----存在数据库和redis同步性问题。
@SpringBootApplication
@EnableCaching
@MapperScan("com.jarye.mapper")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
@Cacheable(cacheNames = "members", key = "'getListMembers'")
@RequestMapping("/getListMembers")
public List<MemberEntity> getListMembers() {
return userMapper.findMemberAll();
}
5.其他缓存
和redis缓存一样的Ehcache、Memcache等第三方缓存、JVM自带内置缓存、数据库缓存
6.缓存需要考虑的问题
1、Redis与数据库一致性问题:mq订阅binlog,可同步数据一致性问题
2、JVM与Redis保持一致性问题:出现不一致的时候,同步数据库的值为一致。
3、Nginx缓存与服务器端真实缓存一致问题:
a. 使用版本号控制
b. 手动清除Nginx缓存,需要物理删除
c. 使用lua+openresty实现动态商品详情页面
推荐阅读:
<<<高并发架构的整体思路
<<<一个网站访问慢的真正原因
<<<高并发情况下,接口的代码会存在哪些问题
<<<压缩静态资源减少带宽传输的方式
<<<动静分离架构模式
<<<后端服务的雪崩效应及解决思路
<<<服务的隔离、降级和熔断
<<<服务限流之计数器方式
<<<服务限流之滑动窗口计数
<<<服务限流之令牌桶算法
<<<服务限流之漏桶算法
<<<漏桶算法和令牌桶算法的区别
<<<自定义封装限流算法
<<<应用级限流
<<<接入层限流