一,关于Redisson
Jedis 和 lettuce 是比较纯粹的 Redis 客户端,几乎没提供什么高级功能。Redisson 的优势是提供了很多开箱即用的 Redis 高级功能,很多分布式相关操作服务,例如,分布式锁,分布式集合,可通过Redis支持延迟队列等。
二,在项目中的使用
1)pom.xml中添加依赖包
org.redisson
redisson-spring-boot-starter
3.17.6
2)在配置文件application.yml中通过spring.redis.redisson.file 来指定redisson的配置文件名称
# =======================================================================
redisson:
file: classpath:redisson.yml
# =======================================================================
添加redisson.yml配置,参考文档:2. 配置方法 · redisson/redisson Wiki · GitHub
# 单节点配置
singleServerConfig:
# 节点地址
address: redis://127.0.0.1:6379
# 密码
password:
# 客户端名称
clientName:
# 数据库编号,选择使用哪个数据库0~15
database: 6
# 连接空闲超时,单位:毫秒
idleConnectionTimeout: 10000
# 连接超时,单位:毫秒
connectTimeout: 10000
# 命令等待超时,单位:毫秒
timeout: 3000
# 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。
# 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
retryAttempts: 3
# 命令重试发送时间间隔,单位:毫秒
retryInterval: 1500
# 单个连接最大订阅数量
subscriptionsPerConnection: 5
# 发布和订阅连接的最小空闲连接数
subscriptionConnectionMinimumIdleSize: 1
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
# 最小空闲连接数
connectionMinimumIdleSize: 32
# 连接池大小
connectionPoolSize: 64
# DNS监测时间间隔,单位:毫秒
dnsMonitoringInterval: 5000
#=================================================================================
# 线程池数量,默认值: 当前处理核数量 * 2
threads: 0
# Netty线程池数量,默认值: 当前处理核数量 * 2
nettyThreads: 0
# 编码
codec:
class: org.redisson.codec.JsonJacksonCodec
# 传输模式
transportMode : "NIO"
3)自定义redisson配置类
package com.qi.study.springboot.config;
import java.io.IOException;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfiguation {
@Bean
public RedissonClient redisson() throws IOException {
// 本例子使用的是yaml格式的配置文件,读取使用Config.fromYAML,如果是Json文件,则使用Config.fromJSON
Config config = Config.fromYAML(RedissonConfiguation.class.getClassLoader().getResource("redisson.yml"));
return Redisson.create(config);
}
}
4)编写redisson操作工具类-这里主要是分布式锁的使用
package com.qi.study.springboot.util;
import java.util.concurrent.TimeUnit;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RedissonUtil {
private final static Logger LOGGER = LoggerFactory.getLogger(RedissonUtil.class);
private RedissonClient redissonClient;
@Autowired
public void setRedisson(RedissonClient redisson) {
this.redissonClient = redisson;
}
/**
* 加锁
* @param lockKey
* @return
*/
public RLock lock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock();
LOGGER.info("RedissonUtil加锁成功,Redis Lock key :{}", lockKey);
return lock;
}
/**
* 带超时的锁
* @param lockKey
* @param timeout 超时时间 单位:秒
*/
public RLock lock(String lockKey, int timeout) {
return lock(lockKey, timeout, TimeUnit.SECONDS);
}
/**
* 带超时的锁
* @param lockKey
* @param timeout 超时时间
* @param unit 时间单位
*/
public RLock lock(String lockKey, int timeout, TimeUnit unit ) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(timeout, unit);
LOGGER.info("RedissonUtil加锁成功,Redis Lock key :{}", lockKey);
return lock;
}
/**
* 尝试获取锁
* @param lockKey
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放锁时间
* 默认时间单位:秒
* @return
*/
public boolean tryLock(String lockKey, int waitTime, int leaseTime) {
return tryLock(lockKey, waitTime, leaseTime, TimeUnit.SECONDS);
}
/**
* 尝试获取锁
* @param lockKey
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放锁时间
* @param unit 时间单位
* @return
*/
public boolean tryLock(String lockKey, int waitTime, int leaseTime, TimeUnit unit) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
}
/**
* 释放锁
* @param lockKey
*/
public void unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
// 释放锁,判断要解锁的key是否已被锁定并且是否被当前线程保持
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
LOGGER.info("RedissonUtil释放锁成功,Redis Lock key :{}", lockKey);
}
}
}
三,添加测试代码
@RequestMapping("/redis/setLock")
public JsonResult setLock(@RequestParam(name="lockKey") String lockKey){
redissonUtil.lock(lockKey);
return JsonResultBuilder.ok();
}
@RequestMapping("/redis/pushLock")
public JsonResult pushLock(@RequestParam(name="lockKey") String lockKey){
redissonUtil.unlock(lockKey);
return JsonResultBuilder.ok();
}
四,报错说明:
该篇是基于上一篇整合swagger3之后的项目添加的,发现添加redisson包之后启动会报错,解决办法是在SwaggerConfiguration.java配置类中添加如下代码:
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private void customizeSpringfoxHandlerMappings(List mappings) {
List copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
五,启动测试
上面我们配置的database=6,请求发送后通过redis 连接工具查看:
六,源代码下载:https://download.csdn.net/download/MyNoteBlog/86661443