1、创建springboot项目,添加相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.8</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- redis,使用jedis客户端排除lettuce -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2、application.yml配置文件添加配置
spring:
redis:
host: localhost
port: 6379
password:
timeout: 5000
database: 0
3、管理RedisTemplate
package com.company.springbootinterviewquestions.sys.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* 缓存的配置
*
* @author zj
* @date 2020/7/9 11:43
*/
@Configuration
public class CacheConfig {
@Autowired
private YmlBean ymlBean;
/**
* redis缓存类
*
* @author zj
* @date 2020/4/19 17:53
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(connectionFactory);
Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// 字符串key序列化方式
redisTemplate.setKeySerializer(RedisSerializer.string());
// 字符串value序列化方式
redisTemplate.setValueSerializer(RedisSerializer.string());
// Hash key序列化方式
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
// Hash value序列化方式
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// 设置序列化方式, 前面只是声明, 该方法才实际注入序列化方式
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
4、配置文件参数
package com.company.springbootinterviewquestions.sys.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* 配置文件参数
*
* @author 35997
* @date 2022/4/20
*/
@Data
@Configuration
public class YmlBean {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String redisPort;
}
5、缓存雪崩控制类
package com.company.springbootinterviewquestions.lock.redis;
import cn.hutool.core.util.ObjectUtil;
import com.company.springbootinterviewquestions.core.pojo.response.ResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.concurrent.locks.ReentrantLock;
/**
* 缓存雪崩控制类
*
* @author 35997
* @date 2022/4/15
*/
@RequestMapping("/cache/avalanche")
@Controller
public class CacheAvalancheController {
ReentrantLock reentrantLock = new ReentrantLock();
@Autowired
private RedisTemplate redisTemplate;
/**
* 互斥锁解决缓存雪崩
* @return
*/
@RequestMapping("/mutex")
@ResponseBody
public ResponseData mutex(String key){
Object value = redisTemplate.opsForValue().get(key);
if (ObjectUtil.isEmpty(value)){
if (reentrantLock.tryLock()) {
try {
value = redisTemplate.opsForValue().get(key);
if(ObjectUtil.isEmpty(value)){
data();
}
} catch (Exception e){
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}else{
value = redisTemplate.opsForValue().get(key);
if(ObjectUtil.isEmpty(value)){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
mutex(key);
}
}
}
return ResponseData.success(value);
}
/**
* 模拟数据库中的数据
*/
public void data(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
redisTemplate.opsForValue().set("aa", "数据");
}
}
到此,大功告成。