项目使用的为 spring框架
redis配置:
文件名:application.properties
配置代码:
# Redis 配置
spring.redis.host=192.168.10.20
spring.redis.port=6379
spring.redis.database=105
spring.redis.password=CN66law123
spring.redis.timeout=5000ms
Redis帮助类代码:
/**
* Redis帮助类
*
* @author wangwei
*/
@Component
public class RedisUtils {
private final StringRedisTemplate redisTemplate;
private final RedissonClient client;
static final int RANDOM_CACHE_TIME_LEVEL_1 = 60;
static final int RANDOM_CACHE_TIME_LEVEL_2 = 300;
public RedisUtils(StringRedisTemplate redisTemplate, RedissonClient client) {
this.redisTemplate = redisTemplate;
this.client = client;
}
/**
* 获取所有hash数据
*/
public <T> Map<String, T> hashGetAll(String key, Class<T> clazz) {
var map = redisTemplate.opsForHash().entries(key);
var res = new HashMap<String, T>(map.size());
if (map.isEmpty()) {
return res;
}
map.forEach((k, v) -> {
if (v instanceof String) {
res.put(k.toString(), (T) v);
} else {
res.put(k.toString(), JsonUtils.parseObject(v.toString(), clazz));
}
});
return res;
}
/**
* 获取hash数据
*/
public <T> T hashGet(String key, String dataKey, Class<T> clazz) {
var value = redisTemplate.opsForHash().get(key, dataKey);
if (value == null || StrUtil.isBlank(value.toString())) {
return null;
}
return JsonUtils.parseObject(value.toString(), clazz);
}
/**
* 设置所有hash数据
*/
public <T> void hashSetAll(String key, Map<String, T> map, int cacheTime, boolean alwaysSetExpire, boolean appendRandomCacheTime) {
var keyExists = redisTemplate.hasKey(key);
Map<String, String> strMap = new HashMap<>(map.size());
map.forEach((k, v) -> strMap.put(k, JsonUtils.toJsonString(v)));
redisTemplate.opsForHash().putAll(key, strMap);
if (keyExists == null || !keyExists || alwaysSetExpire) {
long cacheSeconds = appendRandomCacheTime(cacheTime, appendRandomCacheTime);
redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
}
}
/**
* 设置hash数据
*/
public <T> void hashSet(String key, String dataKey, T t, int cacheTime, boolean alwaysSetExpire, boolean appendRandomCacheTime) {
var json = JsonUtils.toJsonString(t);
var keyExists = redisTemplate.hasKey(key);
redisTemplate.opsForHash().put(key, dataKey, json);
if (keyExists == null || !keyExists || alwaysSetExpire) {
long cacheSeconds = appendRandomCacheTime(cacheTime, appendRandomCacheTime);
redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
}
}
/**
* 设置指定 key 的值
*
* @param key key
* @param t t
* @param cacheTime cacheTime
* @param alwaysSetExpire alwaysSetExpire
* @param appendRandomCacheTime appendRandomCacheTime
* @param <T> <T>
*/
public <T> void set(String key, T t, int cacheTime, boolean alwaysSetExpire, boolean appendRandomCacheTime) {
var json = JsonUtils.toJsonString(t);
var keyExists = redisTemplate.hasKey(key);
redisTemplate.opsForValue().set(key, json);
if (keyExists == null || !keyExists || alwaysSetExpire) {
long cacheSeconds = appendRandomCacheTime(cacheTime, appendRandomCacheTime);
redisTemplate.expire(key, cacheSeconds, TimeUnit.SECONDS);
}
}
/**
* 获取指定 key 的值
*
* @param key key
* @param clazz clazz
* @param <T> <T>
* @return T
*/
public <T> T get(String key, Class<T> clazz) {
var value = redisTemplate.opsForValue().get(key);
if (StrUtil.isBlank(value)) {
return null;
}
return JsonUtils.parseObject(value, clazz);
}
/**
* 获取自增值
*
* @param key key
* @param delta delta
* @return 自增值
*/
public Long increment(String key, Long delta) {
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 提交数据到延时队列
*
* @param queueName 队列名
* @param t 数据实体
* @param delay 延时时间
* @param timeUnit 延时单位
* @param <T> 数据类型
*/
public <T> void offerDelayQueue(String queueName, T t, Long delay, TimeUnit timeUnit) {
RBlockingQueue<String> blockingQueue = client.getBlockingQueue(queueName);
RDelayedQueue<String> delayedQueue = client.getDelayedQueue(blockingQueue);
delayedQueue.offer(JsonUtils.toJsonString(t), delay, timeUnit);
}
/**
* 获取延时队列数据
*
* @param queueName 队列名
* @param <T> 数据类型
* @return 数据结果
*/
public <T> T takeDelayQueue(String queueName, Class<T> clazz) {
RBlockingQueue<String> blockingQueue = client.getBlockingQueue(queueName);
client.getDelayedQueue(blockingQueue);
try {
if (blockingQueue.isEmpty()) {
return null;
}
var data = blockingQueue.take();
return JsonUtils.parseObject(data, clazz);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
/**
* 尝试获取锁
*
* @param lockKey 加锁key
* @param timeUnit 时间单位
* @param leaseTime 上锁后自动释放锁时间
* @param waitTime 等待时间
* @return 结果标识
*/
public Boolean tryLock(String lockKey, TimeUnit timeUnit, long leaseTime, long waitTime) {
RLock lock = client.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, timeUnit);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
/**
* 检测是否被加锁
*
* @param lockKey 加锁key
* @return 标识
*/
public Boolean isLocked(String lockKey) {
RLock lock = client.getLock(lockKey);
return lock.isLocked();
}
/**
* 释放锁
*
* @param lockKey 加锁key
*/
public void unLock(String lockKey) {
RLock lock = client.getLock(lockKey);
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
/**
* 缓存时间随机增加时间长度,避免缓存雪崩
* cacheTime ∈ (0, 1],append ∈ [0.1,0.3];
* cacheTime ∈ (1, 5],append ∈ [0.3,1.0];
* cacheTime ∈ (5,∞),append ∈ [1.0,5.0];
* append为随机增加的时间长度,单位为:min
*
* @param cacheTime 缓存时间
* @param appendRandomCacheTime 是否自动追加随机缓存时长
* @return 缓存时间(单位s)
*/
private long appendRandomCacheTime(int cacheTime, boolean appendRandomCacheTime) {
long cacheSeconds = TimeoutUtils.toSeconds(cacheTime, TimeUnit.MINUTES);
if (appendRandomCacheTime) {
int min, max;
if (cacheTime <= RANDOM_CACHE_TIME_LEVEL_1) {
min = 6;
max = 18;
} else if (cacheTime <= RANDOM_CACHE_TIME_LEVEL_2) {
min = 18;
max = 60;
} else {
min = 60;
max = 5 * 60;
}
cacheSeconds += RandomUtil.randomInt(min, max);
}
return cacheSeconds;
}
/**
* 批量获取
*
* @param key key
* @param clazz clazz
* @param <T> <T>
* @return List<T>
*/
public <T> List<T> multiGet(Collection<String> key, Class<T> clazz) {
var list = redisTemplate.opsForValue().multiGet(key);
if (list == null || list.size() <= 0) {
return new ArrayList<>();
}
List<T> res = new ArrayList<>();
list.forEach(item -> {
if (item != null) {
res.add(JSONUtil.toBean(item, clazz));
}
});
return res;
}
}