正在显示
1 个修改的文件
包含
40 行增加
和
9 行删除
@@ -15,6 +15,16 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; | @@ -15,6 +15,16 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
15 | /** | 15 | /** |
16 | * @author 子诚 | 16 | * @author 子诚 |
17 | * Description:自定义Redis作为mybatis二级缓存实现 | 17 | * Description:自定义Redis作为mybatis二级缓存实现 |
18 | + * 问题描述:缓存穿透、缓存雪崩 | ||
19 | + * <p> | ||
20 | + * 缓存穿透:就是说利用一些列措施,使得访问避开了缓存,直接访问数据库,使得数据库不堪重负引起的问题。比如(压测)访问数据库中不存在的数据 | ||
21 | + * 解决方案:读取数据库,不存在;依旧生成对应的key,放到缓存中,但是对应的value是null(mybatis的二级缓存是这样解决的)。 | ||
22 | + * 下次再次访问的话,就是读取缓存。 | ||
23 | + * <p> | ||
24 | + * 缓存雪崩:是指在某一特殊时刻,缓存中的缓存全部失效,然后这一时刻又有大量的数据库访问,导致数据库不堪重负。 | ||
25 | + * 解决方案:根据业务的不同设置不同的缓存失效时间。 | ||
26 | + * 比如:这个项目,做了3个namespace的缓存,其中一个namespace,共有5个Mapper指向它。所以选择使用范围内的随机值,来做缓存失效时间 | ||
27 | + * <p> | ||
18 | * 时间:2020/8/6 9:37 | 28 | * 时间:2020/8/6 9:37 |
19 | */ | 29 | */ |
20 | public class RedisCache implements Cache { | 30 | public class RedisCache implements Cache { |
@@ -30,11 +40,6 @@ public class RedisCache implements Cache { | @@ -30,11 +40,6 @@ public class RedisCache implements Cache { | ||
30 | private static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); | 40 | private static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); |
31 | 41 | ||
32 | /** | 42 | /** |
33 | - * 缓存对象的是失效时间,30分钟 | ||
34 | - */ | ||
35 | - private static final long CACHE_TIME_IN_MINT = 30; | ||
36 | - | ||
37 | - /** | ||
38 | * 当前放入缓存的mapper的namespace | 43 | * 当前放入缓存的mapper的namespace |
39 | */ | 44 | */ |
40 | private final String id; | 45 | private final String id; |
@@ -67,8 +72,34 @@ public class RedisCache implements Cache { | @@ -67,8 +72,34 @@ public class RedisCache implements Cache { | ||
67 | { | 72 | { |
68 | RedisTemplate redisTemplate = getRedisTemplate(); | 73 | RedisTemplate redisTemplate = getRedisTemplate(); |
69 | // 使用redis的hash类型作为缓存存储模型 | 74 | // 使用redis的hash类型作为缓存存储模型 |
70 | - redisTemplate.opsForHash().put(id.toString(), key.toString(), value); | ||
71 | - redisTemplate.expire(id.toString(), CACHE_TIME_IN_MINT, TimeUnit.MINUTES); | 75 | + redisTemplate.opsForHash().put(id.toString(), encryptionKey(key.toString()), value); |
76 | + | ||
77 | + /** | ||
78 | + * 根据业务的不同,设置不同的缓存时间,解决掉缓存雪崩 | ||
79 | + */ | ||
80 | + if (id.equals("com.sunyo.wlpt.message.bus.service.mapper.VirtualHostMapper")) { | ||
81 | + // 设置缓存时间 | ||
82 | + redisTemplate.expire(id.toString(), random(1, 3), TimeUnit.HOURS); | ||
83 | + } | ||
84 | + | ||
85 | + if (id.equals("com.sunyo.wlpt.message.bus.service.mapper.UserMessageBindingMapper")) { | ||
86 | + // 设置缓存时间 | ||
87 | + redisTemplate.expire(id.toString(), random(60, 100), TimeUnit.MINUTES); | ||
88 | + } | ||
89 | + | ||
90 | + if (id.equals("com.sunyo.wlpt.message.bus.service.mapper.UserInfoMapper")) { | ||
91 | + // 设置缓存时间 | ||
92 | + redisTemplate.expire(id.toString(), random(30, 50), TimeUnit.MINUTES); | ||
93 | + } | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * | ||
98 | + */ | ||
99 | + public int random(int low, int high) | ||
100 | + { | ||
101 | + int num = ((int) (Math.random() * (high - low))) + low; | ||
102 | + return num; | ||
72 | } | 103 | } |
73 | 104 | ||
74 | /** | 105 | /** |
@@ -79,7 +110,7 @@ public class RedisCache implements Cache { | @@ -79,7 +110,7 @@ public class RedisCache implements Cache { | ||
79 | { | 110 | { |
80 | RedisTemplate redisTemplate = getRedisTemplate(); | 111 | RedisTemplate redisTemplate = getRedisTemplate(); |
81 | //根据key 从redis的hash类型中获取数据 | 112 | //根据key 从redis的hash类型中获取数据 |
82 | - return redisTemplate.opsForHash().get(id.toString(), key.toString()); | 113 | + return redisTemplate.opsForHash().get(id.toString(), encryptionKey(key.toString())); |
83 | } | 114 | } |
84 | 115 | ||
85 | /** | 116 | /** |
@@ -133,7 +164,7 @@ public class RedisCache implements Cache { | @@ -133,7 +164,7 @@ public class RedisCache implements Cache { | ||
133 | /** | 164 | /** |
134 | * 封装一个对key进行md5处理方法 | 165 | * 封装一个对key进行md5处理方法 |
135 | */ | 166 | */ |
136 | - private String getKeyToMD5(String key) | 167 | + private String encryptionKey(String key) |
137 | { | 168 | { |
138 | return DigestUtils.md5DigestAsHex(key.getBytes()); | 169 | return DigestUtils.md5DigestAsHex(key.getBytes()); |
139 | } | 170 | } |
-
请 注册 或 登录 后发表评论