文章目录
1.redis服务端搭建
1.1依赖导入
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
1.2redis.properties配置文件
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
redis.timeout=5000
1.3redis服务controller
@RestController
@RequestMapping("/redis")
public class RedisController {
@GetMapping("/get/{key}")
public AjaxResult get(@PathVariable("key") String key){
String result = RedisUtils.INSTANCE.get(key);
AjaxResult ajaxResult = null;
if ("".equals(result) || result==null){
ajaxResult = AjaxResult.me().setResultObj(null);
}else {
ajaxResult = AjaxResult.me().setResultObj(result);
}
return ajaxResult;
}
@PostMapping("/set")
public AjaxResult set(@RequestParam("key") String key,@RequestParam("value") String value){
RedisUtils.INSTANCE.set(key, value);
return AjaxResult.me();
}
@PostMapping("/setex")
public AjaxResult setex(@RequestParam("key") String key,
@RequestParam("value") String value,
@RequestParam("seconds") int seconds){
RedisUtils.INSTANCE.setex(key, value,seconds);
return AjaxResult.me();
}
}
1.4redis工具类
public enum RedisUtils {
INSTANCE;
static JedisPool jedisPool = null;
static {
//1 创建连接池配置对象
JedisPoolConfig config = new JedisPoolConfig();
//2 进行配置-四个配置
config.setMaxIdle(1);//最小连接数
config.setMaxTotal(11);//最大连接数
config.setMaxWaitMillis(10 * 1000L);//最长等待时间
config.setTestOnBorrow(true);//测试连接时是否畅通
//3 通过配置对象创建连接池对象
Properties properties = null;
try {
properties = new Properties();
properties.load(RedisUtils.class.getClassLoader().getResourceAsStream("redis.properties"));
} catch (IOException e) {
e.printStackTrace();
}
String host = properties.getProperty("redis.host");
String port = properties.getProperty("redis.port");
String password = properties.getProperty("redis.password");
String timeout = properties.getProperty("redis.timeout");
jedisPool = new JedisPool(config, host, Integer.valueOf(port),Integer.valueOf(timeout), password);
}
//获取连接
public Jedis getSource() {
return jedisPool.getResource();
}
//关闭资源
public void closeSource(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
/**
* 设置字符值
*
* @param key
* @param value
*/
public void set(String key, String value) {
Jedis jedis = getSource();
jedis.set(key, value);
closeSource(jedis);
}
public void setex(String key, String value,int seconds) {
Jedis jedis = getSource();
jedis.setex(key,seconds,value);
closeSource(jedis);
}
/**
* 设置
* @param key
* @param value
*/
public void set(byte[] key, byte[] value) {
Jedis jedis = getSource();
jedis.set(key, value);
closeSource(jedis);
}
/**
*
* @param key
* @return
*/
public byte[] get(byte[] key) {
Jedis jedis = getSource();
try {
return jedis.get(key);
} catch (Exception e) {
e.printStackTrace();
} finally {
closeSource(jedis);
}
return null;
}
/**
* 设置字符值
*
* @param key
*/
public String get(String key) {
Jedis jedis = getSource();
try {
return jedis.get(key);
} catch (Exception e) {
e.printStackTrace();
} finally {
closeSource(jedis);
}
return null;
}
}
2Feign负载均衡模块
因为有可能有多个服务会用到redis缓存服务,所以将feign独立抽出
2.1Feign依赖
<!--导入负载均衡feign包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2Feign接口映射
feign接口映射rediscontroller
//value为feign访问对象的服务名
@FeignClient(value = "redis-server")
public interface RedisClient {
@GetMapping("/redis/get/{key}")
public AjaxResult get(@PathVariable("key") String key);
@PostMapping("/redis/set")
public AjaxResult set(@RequestParam("key") String key,
@RequestParam("value") String value);
@PostMapping("/setex")
public AjaxResult setex(@RequestParam("key") String key,
@RequestParam("value") String value,
@RequestParam("seconds") int seconds);
}
回调方法
public class RedisClientFallBack implements RedisClient {
@Override
public AjaxResult get(String key) {
return AjaxResult.me().setSuccess(false).setMessage("当前服务不可用");
}
@Override
public AjaxResult set(String key, String value) {
return AjaxResult.me().setSuccess(false).setMessage("当前服务不可用");
}
@Override
public AjaxResult setex(String key, String value, int seconds) {
return AjaxResult.me().setSuccess(false).setMessage("当前服务不可用");
}
}
3redis缓存穿透和缓存击穿
3.1:缓存击穿是指,一个热点key有着很高的并发量,当该key过期瞬间,持续高并发请求直接请求数据库
3.2:缓存穿透:在redis缓存中没有该数据,数据库中也没有该数据,如果持续这样的请求会造成数据库压力变大,解决方法,当数据库中没有该请求的数据时,redis将该请求的key的值设为空,并为该key设置一个过期时间,过期时间不宜过长。
3.3 缓存雪崩:缓存中的key同一时间大量过期,造成直接访问数据库的情况,解决方法:将热点数据分部到不同的redis服务中,
给key设置随机过期时间,数据预热,先把数据访问一次,使其缓存到redis中