赞
踩
目录
简介
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它提供了一系列的分布式的Java常用对象,和许多分布式服务。
特点:
- 支持 Redis 单节点(single)模式、哨兵(sentinel)模式、主从(Master/Slave)模式以及集群(Redis Cluster)模式
- RMap中有一个功能是可以设置键值对的过期时间的,并可以注册键值对的事件监听器,但非实时性
- 由Redisson默认的编码器为JsonJacksonCodec,JsonJackson在序列化有双向引用的对象时,会出现无限循环异常
- 所以不用redission其他自带的二进制编码器,自行实现编码器(相互注入,用fastjson能 正常序列化到redis,而JsonJackson则抛出无限循环异常)
- Redisson对订阅发布的封装是RTopic,在事件发布后,订阅方需要延时一下才能收到事件。
- Redisson底层采用的是Netty 框架。支持Redis 2.8以上版本,支持Java1.6+以上版本
pom引入
<!--redis依赖配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.15.0</version> </dependency>yml
spring: redis: database: 0 # Redis数据库索引(默认为0) port: 6379 # Redis服务器连接端口 password: 123456 # Redis服务器连接密码(默认为空) jedis: pool: max-active: 8 # 连接池最大连接数(使用负值表示没有限制) max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 8 # 连接池中的最大空闲连接 min-idle: 0 # 连接池中的最小空闲连接 timeout: 3000ms # 连接超时时间(毫秒) host: aliyuncs.com # Redis服务器地址(单点配置) #sentinel: # 集群配置 #master: master1 #nodes: 172.16.33.216:16001,172.16.33.216:16002方法
RLock rLock = redisson.getLock(KEY); // 最常见的使用方法 rLock.lock(); // 最长等待时间waitTime,最长持有锁的时间 holdTime, 第三个是单位 rLock.tryLock(20, 15, TimeUnit.SECONDS) // 500s 后自动释放锁 rLock.lock(500, TimeUnit.SECONDS); // 释放锁 rLock.unlock(); // 异步执行 RLock lock = redisson.getLock("anyLock"); lock.lockAsync(); lock.lockAsync(10, TimeUnit.SECONDS); Future<Boolean> res = lock.tryLockAsync(100, 10, TimeUnit.SECONDS); // 分布式可重入公平锁(可异步执行,同上) RLock fairLock = redisson.getFairLock("anyLock"); // 最常见的使用方法 fairLock.lock(); // 联锁 RLock lock1 = redissonInstance1.getLock("lock1"); RLock lock2 = redissonInstance2.getLock("lock2"); RLock lock3 = redissonInstance3.getLock("lock3"); RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); // 同时加锁:lock1 lock2 lock3 // 所有的锁都上锁成功才算成功。 lock.lock(); ... lock.unlock(); // 读写锁,分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。 RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock"); // 最常见的使用方法 rwlock.readLock().lock(); // 或 rwlock.writeLock().lock();自定义codec
Redisson提供的几种数据序列化对象编码应用:https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
想自定义codec,需要自己初始化redissonClient,再调用Redisson.create(config),而通过 redissonClient.getConfig().setCodec(...)是无效的
config.setCodec(new FastJsonCodec()); redisson = Redisson.create(config);FastJsonCodec.java
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; import org.redisson.client.codec.BaseCodec; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Encoder; import java.io.IOException; /** * @Author: s * @Date: 2021/4/20 22:32 */ public class FastJsonCodec extends BaseCodec { private final Encoder encoder = in -> { ByteBuf out = ByteBufAllocator.DEFAULT.buffer(); try { ByteBufOutputStream os = new ByteBufOutputStream(out); JSON.writeJSONString(os, in, SerializerFeature.WriteClassName); return os.buffer(); } catch (IOException e) { out.release(); throw e; } catch (Exception e) { out.release(); throw new IOException(e); } }; private final Decoder<Object> decoder = (buf, state) -> JSON.parseObject(new ByteBufInputStream(buf), Object.class); @Override public Decoder<Object> getValueDecoder() { return decoder; } @Override public Encoder getValueEncoder() { return encoder; } }工具类
import org.redisson.Redisson; import org.redisson.api.RBucket; import org.redisson.api.RList; import org.redisson.api.RLock; import org.redisson.api.RMapCache; import org.redisson.api.RScoredSortedSet; import org.redisson.api.RSet; import org.redisson.api.RedissonClient; import org.redisson.client.codec.StringCodec; import org.redisson.config.Config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.io.IOException; import java.util.concurrent.TimeUnit; /** * @author * @version */ @Configuration public class RedissonCache { private Logger logger = LoggerFactory.getLogger(getClass()); /** * 默认缓存时间 */ private static final Long DEFAULT_EXPIRED = 5 * 60L; /** * redis key前缀 */ private static final String REDIS_KEY_PREFIX = ""; /** * redisson client对象 */ private RedissonClient redisson; /** * redis host */ @Value("${spring.redis.host}") private String host; /** * redis password */ @Value("${spring.redis.password}") private String password; @Value("${spring.redis.port}") private Integer port; /** * 连接超时时间 */ private Integer connectTimeout = 3000; /** * 初始化连接 * * @throws IOException */ @PostConstruct public void init() throws IOException { Config config = new Config(); config.useSingleServer() .setAddress("redis://"+ host+":"+port) .setPassword(password) .setDatabase(0) .setPingTimeout(3000) .setTimeout(5000) .setSubscriptionConnectionMinimumIdleSize(1) .setSubscriptionConnectionPoolSize(256) .setConnectTimeout(connectTimeout) .setConnectionPoolSize(256) .setConnectionMinimumIdleSize(1) .setRetryAttempts(3) .setRetryInterval(3000) .setIdleConnectionTimeout(30000) .setClientName("com.meiguang.mgframework.extend.redis.RedisCache"); if (redisson == null) { redisson = Redisson.create(config); logger.info( "redis连接成功,server={}", host); } else { logger.warn("redis 重复连接,config={}", config); } } /** * 读取缓存 * * @param key 缓存key * @param <T> * @return 缓存返回值 */ public <T> T get(String key) { RBucket<T> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key); return bucket.get(); } /** * 以string的方式读取缓存 * * @param key 缓存key * @return 缓存返回值 */ public String getString(String key) { RBucket<String> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key, StringCodec.INSTANCE); return bucket.get(); } /** * 设置缓存(注:redisson会自动选择序列化反序列化方式) * * @param key 缓存key * @param value 缓存值 * @param <T> */ public <T> void put(String key, T value) { RBucket<T> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key); bucket.set(value, DEFAULT_EXPIRED, TimeUnit.SECONDS); } /** * 以string的方式设置缓存 * * @param key * @param value */ public void putString(String key, String value) { RBucket<String> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key, StringCodec.INSTANCE); bucket.set(value, DEFAULT_EXPIRED, TimeUnit.SECONDS); } /** * 以string的方式保存缓存(与其他应用共用redis时需要使用该函数) * * @param key 缓存key * @param value 缓存值 * @param expired 缓存过期时间 */ public void putString(String key, String value, long expired) { RBucket<String> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key, StringCodec.INSTANCE); bucket.set(value, expired <= 0 ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS); } /** * 如果不存在则写入缓存(string方式,不带有redisson的格式信息) * * @param key 缓存key * @param value 缓存值 * @param expired 缓存过期时间 */ public boolean putStringIfAbsent(String key, String value, long expired) { RBucket<String> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key, StringCodec.INSTANCE); return bucket.trySet(value, expired <= 0 ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS); } /** * 如果不存在则写入缓存(string方式,不带有redisson的格式信息)(不带过期时间,永久保存) * * @param key 缓存key * @param value 缓存值 */ public boolean putStringIfAbsent(String key, String value) { RBucket<String> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key, StringCodec.INSTANCE); return bucket.trySet(value); } /** * 设置缓存 * * @param key 缓存key * @param value 缓存值 * @param expired 缓存过期时间 * @param <T> 类型 */ public <T> void put(String key, T value, long expired) { RBucket<T> bucket = redisson.getBucket(REDIS_KEY_PREFIX + key); bucket.set(value, expired <= 0 ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS); } /** * 移除缓存 * * @param key */ public void remove(String key) { redisson.getBucket(REDIS_KEY_PREFIX + key).delete(); } /** * 判断缓存是否存在 * * @param key * @return */ public boolean exists(String key) { return redisson.getBucket(REDIS_KEY_PREFIX + key).isExists(); } /** * 暴露redisson的RList对象 * * @param key * @param <T> * @return */ public <T> RList<T> getRedisList(String key) { return redisson.getList(REDIS_KEY_PREFIX + key); } /** * 暴露redisson的RMapCache对象 * * @param key * @param <K> * @param <V> * @return */ public <K, V> RMapCache<K, V> getRedisMap(String key) { return redisson.getMapCache(REDIS_KEY_PREFIX + key); } /** * 暴露redisson的RSET对象 * * @param key * @param <T> * @return */ public <T> RSet<T> getRedisSet(String key) { return redisson.getSet(REDIS_KEY_PREFIX + key); } /** * 暴露redisson的RScoredSortedSet对象 * * @param key * @param <T> * @return */ public <T> RScoredSortedSet<T> getRedisScoredSortedSet(String key) { return redisson.getScoredSortedSet(REDIS_KEY_PREFIX + key); } /** * 暴露redisson的Lock对象 * * @param key * @return */ public RLock getRedisLock(String key) { return redisson.getLock(REDIS_KEY_PREFIX + key); } @PreDestroy public void close() { try { if (redisson != null) { redisson.shutdown(); } } catch (Exception ex) { logger.error( ex.getMessage(), ex); } } /** * Setter method for property <tt>host</tt>. * * @param host value to be assigned to property host */ public void setHost(String host) { this.host = host; } /** * Setter method for property <tt>password</tt>. * * @param password value to be assigned to property password */ public void setPassword(String password) { this.password = password; } /** * Setter method for property <tt>connectTimeout</tt>. * * @param connectTimeout value to be assigned to property connectTimeout */ public void setConnectTimeout(Integer connectTimeout) { this.connectTimeout = connectTimeout; } }额外功能:https://github.com/redisson/redisson/wiki/10.-%E9%A2%9D%E5%A4%96%E5%8A%9F%E8%83%BD
包括对Redis节点的操作(连接或断开),命令的批量执行以及配置事务属性
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。