准备工作安装redis
可以参考这两位大佬的博文,很详细,因为我用的是阿里云的服务器,所以参考的(1),当然(2)也是可以的,任选一种即可:
(1)《阿里云 CentOS7安装redis4.0.9并开启远程访问》
(2)《CentOS7 linux下yum安装redis以及使用》
在这里贴出一组小tips
进入到bin目录下
查看redis进程
ps -ef | grep redis
停止redis
./redis-cli -h 0.0.0.0 -p 6379 shutdown
启动redis
./redis-server redis.conf
springboot整合redis
1.maven依赖
org.springframework.boot
spring-boot-starter-data-redis
2.选择redis客户端
这里选择了lettuce客户端,为什么不用Jredis,在《spring boot 集成 redis lettuce》这篇博文里解释了,给大佬点赞。
总结一下就是:
# Jedis和Lettuce都是Redis Client
# Jedis 是直连模式,在多个线程间共享一个 Jedis 实例时是线程不安全的,
# 如果想要在多线程环境下使用 Jedis,需要使用连接池,
# 每个线程都去拿自己的 Jedis 实例,当连接数量增多时,物理连接成本就较高了。
# Lettuce的连接是基于Netty的,连接实例可以在多个线程间共享,
# 所以,一个多线程的应用可以使用同一个连接实例,而不用担心并发线程的数量。
# 当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
# 通过异步的方式可以让我们更好的利用系统资源,而不用浪费线程等待网络或磁盘I/O。
# Lettuce 是基于 netty 的,netty 是一个多线程、事件驱动的 I/O 框架,
# 所以 Lettuce 可以帮助我们充分利用异步的优势。
所以选择maven依赖
org.apache.commons
commons-pool2
2.5.0
com.fasterxml.jackson.core
jackson-databind
2.9.6
com.alibaba
fastjson
1.2.47
为什么要添加jackson和fastjson
因为spring-data-redis 里的使用JacksonJsonRedisSerializer序列化(被序列化对象不需要实现Serializable接口,被序列化的结果清晰,容易阅读,而且存储字节少,速度快),我觉得这个json格式不好看,不错,说白了就是格式上不易阅读,还是觉得阿里的fastjson比较适合我的审美观。所以等会要换掉,但是jackson还是要留着,总有不喜欢折腾的同学。
3.配置文件
spring:
#redis
redis:
# Redis服务器地址
host: 你的ip #默认就是localhost
#host: localhost
# Redis服务器连接端口
port: 6379 #默认
# Redis数据库索引(默认为0)
database: 0
# Redis服务器连接密码(默认为空)
password: 你的redis密码
# 连接超时时间(毫秒)
timeout: 10000
# Lettuce
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 10000
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
# 关闭超时时间
shutdown-timeout: 100
4.配置类RedisConfig
package warmer.star.blog.config;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import warmer.star.blog.util.FastJson2JsonRedisSerializer;
import java.lang.reflect.Method;
import java.time.Duration;
/**
* 缓存配置-使用Lettuce客户端,自动注入配置的方式
*/
@Configuration
@EnableCaching //启用缓存
@ConfigurationProperties(prefix = "spring.redis") //指明配置节点
public class RedisConfig extends CachingConfigurerSupport {
// Redis服务器地址
@Value("${spring.redis.host}")
private String host;
// Redis服务器连接端口
@Value("${spring.redis.port}")
private Integer port;
// Redis数据库索引(默认为0)
@Value("${spring.redis.database}")
private Integer database;
// Redis服务器连接密码(默认为空)
@Value("${spring.redis.password}")
private String password;
// 连接超时时间(毫秒)
@Value("${spring.redis.timeout}")
private Integer timeout;
// 连接池最大连接数(使用负值表示没有限制)
@Value("${spring.redis.lettuce.pool.max-active}")
private Integer maxTotal;
// 连接池最大阻塞等待时间(使用负值表示没有限制)
@Value("${spring.redis.lettuce.pool.max-wait}")
private Integer maxWait;
// 连接池中的最大空闲连接
@Value("${spring.redis.lettuce.pool.max-idle}")
private Integer maxIdle;
// 连接池中的最小空闲连接
@Value("${spring.redis.lettuce.pool.min-idle}")
private Integer minIdle;
// 关闭超时时间
@Value("${spring.redis.lettuce.shutdown-timeout}")
private Integer shutdown;
/**
* 自定义缓存key的生成策略。默认的生成策略是看不懂的(乱码内容) 通过Spring 的依赖注入特性进行自定义的配置注入并且此类是一个配置类可以更多程度的自定义配置
*
* @return
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* 缓存配置管理器
*/
@Bean
@Override
public CacheManager cacheManager() {
//以锁写入的方式创建RedisCacheWriter对象
RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(getConnectionFactory());
/*
设置CacheManager的Value序列化方式为JdkSerializationRedisSerializer,
但其实RedisCacheConfiguration默认就是使用
StringRedisSerializer序列化key,
JdkSerializationRedisSerializer序列化value,
所以以下注释代码就是默认实现,没必要写,直接注释掉
*/
// RedisSerializationContext.SerializationPair pair = RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(this.getClass().getClassLoader()));
// RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
//创建默认缓存配置对象
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
return cacheManager;
}
/**
* 获取缓存操作助手对象
*
* @return
*/
@Bean
public RedisTemplate redisTemplate() {
//创建Redis缓存操作助手RedisTemplate对象
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(getConnectionFactory());
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//RedisTemplate对象需要指明Key序列化方式,如果声明StringRedisTemplate对象则不需要
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//以下代码为将RedisTemplate的Value序列化方式由JdkSerializationRedisSerializer
// 更换为Jackson2JsonRedisSerializer/FastJson2JsonRedisSerializer两种方式
//这两种序列化方式结果清晰、容易阅读、存储字节少、速度快,所以推荐更换
//二者选其一
/*//1.jackson序列化方式
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
jackson2JsonRedisSerializer.setObjectMapper(om);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);*/
//2.FastJson序列化方式
FastJson2JsonRedisSerializer fastJson2JsonRedisSerializer =new FastJson2JsonRedisSerializer