企业网站怎么扣费的,建设思政教育网站案例,房地产销售入门培训,郴州市地图文章目录 一、介绍二、方案介绍三、Redis Docker部署四、SpringBoot3 Base代码1. 依赖配置2. 基本代码 五、缓存优化代码1. 校验机制2. 布隆过滤器3. 逻辑优化 一、介绍
当一种请求#xff0c;总是能越过缓存#xff0c;调用数据库#xff0c;就是缓存穿透。 比如当请求一… 文章目录 一、介绍二、方案介绍三、Redis Docker部署四、SpringBoot3 Base代码1. 依赖配置2. 基本代码 五、缓存优化代码1. 校验机制2. 布隆过滤器3. 逻辑优化 一、介绍
当一种请求总是能越过缓存调用数据库就是缓存穿透。 比如当请求一个数据库没有的数据那么缓存也不会有然后就一直请求甚至高并发去请求对数据库压力会增大。
二、方案介绍
如果key具有某种规则那么可以对key增加校验机制不符合直接返回。Redisson布隆过滤器逻辑修改当数据库没有此数据以null为value也插入redis缓存但设置较短的过期时间。
三、Redis Docker部署
docker-compose示例如下redis.conf从这里下载
redis:container_name: redisimage: redis:7.2volumes:- ./redis/redis.conf:/usr/local/etc/redis/redis.confports:- 6379:6379command: [ redis-server, /usr/local/etc/redis/redis.conf ]四、SpringBoot3 Base代码
1. 依赖配置 !-- redis --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency!-- redis 连接线程池 --dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactIdversion2.11.1/version/dependency!-- redisson --dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.24.3/version/dependencyspring: data:redis:host: 192.168.101.65 # Redis服务器的主机名或IP地址port: 6379 # Redis服务器的端口号password: # 用于连接Redis服务器的密码database: 0 # 要连接的Redis数据库的索引号lettuce:pool:max-active: 20 # 连接池中最大的活跃连接数max-idle: 10 # 连接池中最大的空闲连接数min-idle: 0 # 连接池中最小的空闲连接数timeout: 10000 # 连接超时时间毫秒lock-watchdog-timeout: 100 # Redisson的分布式锁的看门狗超时时间毫秒2. 基本代码
要演示的代码很简单就是一个携带courseId请求过来调用下面的service函数然后查询数据库。
Overridepublic CoursePublish getCoursePublish(Long courseId) {return coursePublishMapper.selectById(courseId);}当我们使用redis改造时基本代码如下
Overridepublic CoursePublish getCoursePublishCache(Long courseId) {String key content:course:publish: courseId;//先查询redisObject object redisTemplate.opsForValue().get(key);if (object ! null){String string object.toString();CoursePublish coursePublish JSON.parseObject(string, CoursePublish.class);return coursePublish;}else {//后查询数据库CoursePublish coursePublish getCoursePublish(courseId);if (coursePublish ! null){redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}return coursePublish;}}五、缓存优化代码
1. 校验机制
我这里的id没规则所以加不了跳过。
2. 布隆过滤器
读取yaml配置
Data
Component
ConfigurationProperties(prefix spring.data.redis)
public class RedisProperties {private String host;private int port;private String password;private int database;private int lockWatchdogTimeout;
}
配置RedissonClient
Slf4j
Configuration
public class RedissionConfig {Autowiredprivate RedisProperties redisProperties;Beanpublic RedissonClient redissonClient() {RedissonClient redissonClient;Config config new Config();//starter依赖进来的redisson要以redis://开头其他不用String url redis:// redisProperties.getHost() : redisProperties.getPort();config.useSingleServer().setAddress(url)//.setPassword(redisProperties.getPassword()).setDatabase(redisProperties.getDatabase());try {redissonClient Redisson.create(config);return redissonClient;} catch (Exception e) {log.error(RedissonClient init redis url:[{}], Exception:, url, e);return null;}}
}
把布隆过滤器加到service如下 private RBloomFilterString bloomFilter;PostConstructpublic void init(){//初始化布隆过滤器bloomFilter redissonClient.getBloomFilter(bloom-filter);bloomFilter.tryInit(100, 0.003);ListCoursePublish coursePublishList coursePublishMapper.selectList(new LambdaQueryWrapperCoursePublish());coursePublishList.forEach(coursePublish - {String key content:course:publish: coursePublish.getId();bloomFilter.add(key);});}Overridepublic CoursePublish getCoursePublishCache(Long courseId) {String key content:course:publish: courseId;//布隆过滤器boolean contains bloomFilter.contains(key);if (!contains){return null;}//先查询redisObject object redisTemplate.opsForValue().get(key);if (object ! null){String string object.toString();CoursePublish coursePublish JSON.parseObject(string, CoursePublish.class);return coursePublish;}else {//后查询数据库CoursePublish coursePublish getCoursePublish(courseId);if (coursePublish ! null){bloomFilter.add(key);redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}return coursePublish;}}3. 逻辑优化
当数据库没有此数据以null为value也插入redis缓存但设置较短的过期时间。 //后查询数据库CoursePublish coursePublish getCoursePublish(courseId);if (coursePublish ! null) {bloomFilter.add(key);redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}else {redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish), 10, TimeUnit.SECONDS);}return coursePublish;
相关文章: