SpringBoot集成redisson自带分布式锁-快速集成亲测可用
·
前言
记录项目集成redisson
项目环境
springboot 2.7.5
jdk17
操作
pom.xml
<!-- Redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<scope>compile</scope>
<version>3.11.1</version>
</dependency>
yml配置
spring:
redis:
host: 127.0.0.1 # Redis服务器地址
database: 4 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为空)
timeout: 5000 # 连接超时时间(毫秒)
lettuce:
# 连接池最大阻塞等待时间(毫秒)
shutdown-timeout: 10000
pool:
# 连接池中的最小空闲连接
min-idle: 50
# 连接池中的最大空闲连接
max-idle: 100
# 连接池的最大数据库连接数
max-active: 3000
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 300000
RedissonConfig
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.config.TransportMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Redisson配置类
*
* @author Xx
* @since 2024/10/28 11:12
*/
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private String port;
@Value("${spring.redis.password}")
private String password;
/** 默认使用0号数据库 */
@Value("${spring.redis.database:0}")
private int database;
@Bean
public RedissonClient redisson() {
Config config = new Config();
// 配置线程池
// 线程池数量,0=默认值: 当前处理核数量 * 2
config.setThreads(0)
// Netty线程池数量,0=默认值: 当前处理核数量 * 2
.setNettyThreads(0)
// 设置对象编码器,默认使用JsonJacksonCodec
.setCodec(new JsonJacksonCodec())
// 传输模式,默认NIO
.setTransportMode(TransportMode.NIO);
// 单节点配置
config.useSingleServer()
// 节点地址
.setAddress("redis://" + host + ":" + port)
// Redis认证密码
.setPassword(password)
// 客户端名称
.setClientName("making_friends")
// 数据库编号
.setDatabase(database)
// ==== 连接配置 ====
// 连接空闲超时时间,单位:毫秒
.setIdleConnectionTimeout(10000)
// 连接超时时间,单位:毫秒
.setConnectTimeout(10000)
// 命令等待超时时间,单位:毫秒
.setTimeout(3000)
// 命令失败重试次数
// 如果尝试达到 retryAttempts 仍然不能将命令发送至某个指定的节点时,将抛出错误
// 如果尝试在此限制之内发送成功,则开始启用 timeout 计时
.setRetryAttempts(3)
// 命令重试发送时间间隔,单位:毫秒
.setRetryInterval(1500)
// ==== 订阅配置 ====
// 单个连接最大订阅数量
.setSubscriptionsPerConnection(10)
// 发布和订阅连接的最小空闲连接数
.setSubscriptionConnectionMinimumIdleSize(5)
// 发布和订阅连接池大小
.setSubscriptionConnectionPoolSize(50)
// ==== 连接池配置 ====
// 最小空闲连接数
.setConnectionMinimumIdleSize(32)
// 连接池大小
.setConnectionPoolSize(64)
// ==== DNS监控 ====
// DNS变化扫描间隔,单位:毫秒
.setDnsMonitoringInterval(5000);
// 创建并返回RedissonClient实例
return Redisson.create(config);
}
}
RedissonUtils
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBatch;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RBucket;
import org.redisson.api.RList;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RSemaphore;
import org.redisson.api.RSet;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
/**
* Redisson 工具类
* com.macro.mall.common.util.RedissonUtils
* @author Xx
* dateTime 2024/10/28 11:20
*/
@Slf4j
@Component
public class RedissonUtils {
@Resource
private RedissonClient redissonClient;
// ================ 通用操作 ================
/**
* 删除key
*/
public void del(String key) {
redissonClient.getBucket(key).delete();
}
/**
* 删除key
*/
public void delete(String key) {
redissonClient.getBucket(key).delete();
}
/**
* 批量删除key
*/
public void delete(Collection<String> keys) {
RBatch batch = redissonClient.createBatch();
keys.forEach(key -> batch.getBucket(key).deleteAsync());
batch.execute();
}
/**
* 检查key是否存在
*/
public boolean hasKey(String key) {
return redissonClient.getBucket(key).isExists();
}
/**
* 设置过期时间
*/
public boolean expire(String key, long timeout, TimeUnit unit) {
return redissonClient.getBucket(key).expire(timeout, unit);
}
/**
* 获取过期时间
*/
public long getExpire(String key, TimeUnit unit) {
return redissonClient.getBucket(key).remainTimeToLive();
}
// ================ 对象操作 ================
/**
* 设置对象
*/
public <T> void set(String key, T value) {
RBucket<T> bucket = redissonClient.getBucket(key);
bucket.set(value);
}
/**
* 设置对象带过期时间
*/
public <T> void set(String key, T value, long timeout, TimeUnit unit) {
RBucket<T> bucket = redissonClient.getBucket(key);
bucket.set(value, timeout, unit);
}
/**
* 获取对象
*/
public <T> T get(String key) {
RBucket<T> bucket = redissonClient.getBucket(key);
return bucket.get();
}
// ================ 原子操作 ================
/**
* 原子递增
*/
public long incr(String key, long delta) {
return redissonClient.getAtomicLong(key).addAndGet(delta);
}
/**
* 原子递减
*/
public long decr(String key, long delta) {
return redissonClient.getAtomicLong(key).addAndGet(-delta);
}
// ================ 分布式锁 ================
/**
* 获取可重入锁
*/
public RLock getLock(String key) {
return redissonClient.getLock(key);
}
/**
* 获取公平锁
*/
public RLock getFairLock(String key) {
return redissonClient.getFairLock(key);
}
/**
* 获取读写锁
*/
public RReadWriteLock getReadWriteLock(String key) {
return redissonClient.getReadWriteLock(key);
}
/**
* 获取信号量
*/
public RSemaphore getSemaphore(String key) {
return redissonClient.getSemaphore(key);
}
// ================ 集合操作 ================
/**
* 获取列表
*/
public <T> RList<T> getList(String key) {
return redissonClient.getList(key);
}
/**
* 获取集合
*/
public <T> RSet<T> getSet(String key) {
return redissonClient.getSet(key);
}
/**
* 获取有序集合
*/
public <T> RScoredSortedSet<T> getSortedSet(String key) {
return redissonClient.getScoredSortedSet(key);
}
/**
* 获取映射
*/
public <K, V> RMap<K, V> getMap(String key) {
return redissonClient.getMap(key);
}
// ================ 限流器 ================
/**
* 获取限流器
*/
public RRateLimiter getRateLimiter(String key) {
return redissonClient.getRateLimiter(key);
}
/**
* 创建限流器
*
* @param key 限流器key
* @param rate 每秒允许的请求数
* @param rateInterval 时间间隔,默认1秒
*/
public RRateLimiter createRateLimiter(String key, long rate, long rateInterval) {
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
rateLimiter.trySetRate(RateType.OVERALL, rate, rateInterval, RateIntervalUnit.SECONDS);
return rateLimiter;
}
// ================ 布隆过滤器 ================
/**
* 获取布隆过滤器
*/
public <T> RBloomFilter<T> getBloomFilter(String key) {
return redissonClient.getBloomFilter(key);
}
/**
* 创建布隆过滤器
*
* @param key 布隆过滤器key
* @param expectedInsertions 预期插入数量
* @param falseProbability 误判率
*/
public <T> RBloomFilter<T> createBloomFilter(String key, long expectedInsertions, double falseProbability) {
RBloomFilter<T> bloomFilter = redissonClient.getBloomFilter(key);
bloomFilter.tryInit(expectedInsertions, falseProbability);
return bloomFilter;
}
// ================ 使用示例 ================
/**
* 分布式锁示例
*/
public void lockExample() {
RLock lock = getLock("myLock");
try {
// 尝试加锁,最多等待100秒,上锁10秒后自动解锁
if (lock.tryLock(100, 10, TimeUnit.SECONDS)) {
try {
// 业务逻辑
} finally {
lock.unlock();
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("获取锁异常", e);
}
}
/**
* 限流器示例
*/
public boolean rateLimitExample() {
RRateLimiter rateLimiter = createRateLimiter("myRateLimiter", 10, 1);
// 尝试获取一个令牌
return rateLimiter.tryAcquire(1);
}
/**
* 布隆过滤器示例
*/
public void bloomFilterExample() {
RBloomFilter<String> bloomFilter = createBloomFilter("myBloomFilter", 10000, 0.01);
// 添加元素
bloomFilter.add("item1");
// 判断元素是否存在
boolean exists = bloomFilter.contains("item1");
}
}
分布式锁测试
@Autowired
private RedissonUtils redissonUtils;
@SneakyThrows
@Test
void ts() {
// 获取分布式锁
RLock lock = redissonUtils.getLock("myLock");
// 尝试在 30 秒内获取锁,如果超时则返回 false
if (lock.tryLock(300, 300, java.util.concurrent.TimeUnit.SECONDS)) {
try {
// 执行任务
System.out.println("Executing critical section with distributed lock...");
} finally {
lock.unlock(); // 释放锁
}
} else {
System.out.println("Failed to acquire lock.");
}
}
更多推荐

所有评论(0)