SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

时间:2021-08-01 12:39:08

最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容。

系列(一):主要说了使用IDEA对SpringBoot项目的创建,SpringBoot架构下Web项目Maven的基本依赖及实现。

系列(二):主要讲了Maven父子级项目创建依赖、分环境部署配置及服务端口号统一配置,Dubbo的集成接入、服务层(提供者)分模块实现,提供者(四个)和消费者(一个)的配置及服务调用,微服务落地实现。

系列(三):开始讲了项目及依赖的版本号统一配置管理(子模块和第三方依赖Jar),数据库的连接配置及Redis接入、分布式缓存实现。

系列(四):接口安全实现(防恶意请求、数据篡改等),过滤器配置及签名、token检验拦截、Aop签名实现、防SQL注入等。

学而时习之,不亦说乎。作为我本次推出的系列文章,目的很简单,就是旨意帮助那些不懂分布式开发微服务落地的小伙伴们。目前的IT市场,分布式开发微服务落地已成为主流。SpringBoot,Dubbo,Zookeeper,Redis,Kafka,SpringCloud等也是面试中常问的话题,如果你想在这个行业混下去,这些已经是你必须要学的基础技术知识了,接下来我会根据我近两年的分布式微服务开发经验推出更多的文章。但在前面或接下来的文章中如果有说的不到之处,还希望大家多多指点交流(可添加我微信交流),促使我们一起成长进步,做一个合格的技术人。

SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

今天我要讲的内容是Redis缓存安全防范以及Kafka的接入实现。如:缓存穿透、雪崩及缓存击穿如何解决?缓存服务器宕机或重启,缓存数据不会被丢失等问题。我们带着这些问题进入正题。

Redis缓存安全防范

分布式项目使用Redis缓存,极大的提升了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。另外的一些典型问题,就是缓存穿透、缓存雪崩和缓存击穿。

|| 缓存穿透

缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。如果用户发起id为“-1”或id特别大不存在的数据。这时很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

1,接口层增加校验。对id做基础校验,id<=0的直接拦截;

2,从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value键值对写为key-null,缓存有效时间可以设置短点,如60秒(设置太长会导致正常情况也没法使用),这样可以防止攻击用户反复用同一个id暴力攻击。SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

|| 缓存雪崩

缓存雪崩,是指在某一个时间段,缓存集中过期失效。产生雪崩的原因之一,比如马上就到618了,很快就会迎来一波抢购,这些要抢购的商品在同一时间点(17号23点放入)比较集中的放入了缓存,假设缓存两个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而此时对这批商品的访问查询,都落到了数据库身上,这时对于数据库而言,就会带来极大的压力。

解决方案:

1,在设置数据缓存有效期时,在时间后加上一个随机因子。

2,分散缓存过期时间,将热门类数据缓存时间长一点,冷门类的短一点。

3,设置热点数据永不过期。

SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

|| 缓存击穿

缓存击穿,是指一个key非常热点,高并发集中对这个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像春运期间火车站售票大厅,本来那些设在门口和广场的自助机可以办理售票,结果自助机瞬间全部瘫痪,造成大量买票的人涌进售票大厅人工窗口。

解决方案:

1,设置热点数据永远不过期;

2,加互斥锁,互斥锁参考代码如下:

SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

|| 缓存数据持久化

Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。

RDB

RDB方式是一种快照式的持久化方法,将某一时刻的数据持久化到磁盘中。并在启动时自动加载rdb文件,恢复之前保存的数据。可以在配置文件中配置Redis进行快照保存的时机:

save [seconds] [changes]

例如:save 60 100, 会让Redis每60秒检查一次数据变更情况,如果发生了100次或以上的数据变更,则进行RDB快照保存。可以配置多条save指令,让Redis执行多级的快照保存策略。Redis默认开启RDB快照。

AOF

采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。AOF默认是关闭的,如要开启,进行如下配置:

appendonly yes

  • AOF提供了三种fsync配置,always/everysec/no,通过[appendfsync]指定:appendfsync no:不进行fsync,将flush文件的时机交给OS决定,速度最快;

  • appendfsync always:每写入一条日志就进行一次fsync操作,数据安全性最高,但速度最慢;

  • appendfsync everysec:折中的做法,交由后台线程每秒fsync一次;

推荐阅读:

Spring Boot实现分布式微服务开发实战系列(四)

Spring Boot实现分布式微服务开发实战系列(三)

Spring Boot实现分布式微服务开发实战系列(二)

Spring Boot实现分布式微服务开发实战系列(一)

获取项目源代码,请扫码关注公众号,并发送Springboot获取。

SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范