目标
redisson spring starter
redisson提供了对spring的支持,url地址:https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter#spring-boot-starter 。此starter提供下列spring bean:
pom文件
org.redisson
redisson-spring-boot-starter
3.15.5
org.redisson
redission-spring-data-24
org.redisson
redisson-spring-data-23
3.15.5
引入此starter,可以使用redisson的方式使用redis,也可以使用spring-boot-starter-data-redis中RedisTemplate方式使用redis。
序列化/反序列化
无论是redisson-spring-boot-starter还是spring-boot-starter-data-redis,都提供了RedisTemplate和StringRedisTemplate。
但是多数场景下,redis中的key是String,value是Object,所以增加RedisTemplate类型的bean。
在默认情况下redisson和redisTemplate的序列化/反序列化方式不同,导致不同redis客户端写入的数据只能使用各自的客户端读取,甚至在redis-cli中也无法手工维护。
所以value需要保存为json格式,json格式的序列化/反序列化使用jackson实现。
使用RedisTemplate好处是,RedisTemplate已经提我们反序列化缓存为正确的bean,不需要手工再次把String转换为bean。
可以这样使用:WarehouseInfo warehouseJson = (WarehouseInfo)redisTemplate.opsForValue().get("redisson:redis:warehouse:json");
redisson的json序列化通过配置编码方式实现。把编码设置为org.redisson.codec.JsonJacksonCodec。RedisTemplate需要增加bean定义,并配置序列化/反序列化配置。
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer
这样就实现了redisson和redisTemplate数据兼容,并且在redis-cli中也可以手工维护。
根据配置不同,有多种json格式,如果出现redisson或者RedisTemplate无法处理的json,可以使用StringRedisTemplate,得到String格式的缓存,自己手工想法解析。
————————————————
配置文件
spring:
application:
name: redission-spring
redis:
redisson:
file: classpath:redisson.yml
redisson.yml内容是redis集群模式的样例
clusterServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
failedSlaveReconnectionInterval: 3000
failedSlaveCheckInterval: 60000
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: ! { }
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 24
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
subscriptionMode: "SLAVE"
nodeAddresses:
- "redis://127.0.0.1:6379"
- "redis://127.0.0.1:6380"
scanInterval: 1000
pingConnectionInterval: 0
keepAlive: false
tcpNoDelay: false
threads: 16
nettyThreads: 32
codec: ! { }
transportMode: "NIO"
其中codec指定了json格式的编码方式。redisson这种使用文件的配置方式无法使用spring cloud的配置中心,因为从源码来看,是从工程的本地读取文件。针对这种情况,可以config方式,但是config方式也有一个问题,因为整个config是字符串。
RedisTemplate使用
// 字符串缓存
redisTemplate.opsForValue().set("redisson:redis:string", "test string new");
// bean缓存
WarehouseInfo warehouse = new WarehouseInfo();
warehouse.setWarehouseId(100000000L);
warehouse.setWarehouseName("青岛中心仓");
redisTemplate.opsForValue().set("redisson:redis:warehouse", warehouse);
RedissonClient使用
// 字符串缓存
RBucket bucket = redissonClient.getBucket("redisson:redisson:string");
bucket.set("redisson string");
// bean缓存
WarehouseInfo warehouse = new WarehouseInfo();
warehouse.setWarehouseId(100000079L);
warehouse.setWarehouseName("洛阳中心仓");
RBucket bucket1 = redissonClient.getBucket("redisson:redisson:warehouse");
bucket1.set(warehouse);
// get redisTemplate 写入在缓存
RBucket bucket2 = redissonClient.getBucket("redisson:redis:warehouse");
WarehouseInfo warehouseInfo = bucket2.get();
跨工程使用
采用上述编码方式,如果缓存只在一个工程内使用,序列化/反序列化只有一种,无论采用何种方式,都没有问题。但是,如果跨不同工程使用同一个缓存,
需要序列化/反序列化方式一样,并且也需要全类名也必须一样,但是这点很难做到。解决这个问题的一个思路,编码使用org.redisson.client.codec.StringCodec,
写入缓存之前先手工序列化为json,读取缓存后,手工反序列化json。这样也可以使用StringRedisTemplate。