面试总是会被问到有没有用过分布式锁、redis 锁,大部分读者平时很少接触到,所以只能很无奈的回答 “没有”。本文通过 Spring Boot 整合 redisson 来实现分布式锁,并结合 demo 测试结果。
首先看下大佬总结的图
正文添加依赖
<!--redis--> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-data-redis </artifactId> </dependency> <!--redisson--> <dependency> <groupId> org.redisson </groupId> <artifactId> redisson-spring-boot-starter </artifactId> <version> 3.10.6 </version> </dependency>配置信息
spring: # redis redis: host: 47.103 . 5.190 port: 6379 jedis: pool: # 连接池最大连接数(使用负值表示没有限制) max-active: 100 # 连接池中的最小空闲连接 max-idle: 10 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1 # 连接超时时间(毫秒) timeout: 5000 #默认是索引为0的数据库 database: 0 配置类 /** * redisson 配置,下面是单节点配置: * * @author gourd */ @Configuration publicclass RedissonConfig { @Value ( "${spring.redis.host}" ) private String host; @Value ( "${spring.redis.port}" ) private String port; @Value ( "${spring.redis.password:}" ) private String password; @Bean public RedissonClient redissonClient() { Config config = new Config (); //单节点 config.useSingleServer().setAddress( "redis://" + host + ":" + port); if ( StringUtils .isEmpty(password)) { config.useSingleServer().setPassword( null ); } else { config.useSingleServer().setPassword(password); } //添加主从配置 // config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""}); // 集群模式配置 setScanInterval()扫描间隔时间,单位是毫秒, //可以用"rediss://"来启用SSL连接 // config.useClusterServers().setScanInterval(2000).addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001").addNodeAddress("redis://127.0.0.1:7002"); return Redisson .create(config); } } Redisson 工具类 /** * redis分布式锁帮助类 * * @author gourd * */ publicclass RedisLockUtil { privatestatic DistributedLocker distributedLocker = SpringContextHolder .getBean( "distributedLocker" , DistributedLocker . class ); /** * 加锁 * @param lockKey * @return */ publicstatic RLock lock ( String lockKey) { return distributedLocker. lock (lockKey); } /** * 释放锁 * @param lockKey */ publicstaticvoid unlock( String lockKey) { distributedLocker.unlock(lockKey); } /** * 释放锁 * @param lock */ publicstaticvoid unlock( RLock lock ) { distributedLocker.unlock( lock ); } /** * 带超时的锁 * @param lockKey * @param timeout 超时时间 单位:秒 */ publicstatic RLock lock ( String lockKey, int timeout) { return distributedLocker. lock (lockKey, timeout); } /** * 带超时的锁 * @param lockKey * @param unit 时间单位 * @param timeout 超时时间 */ publicstatic RLock lock ( String lockKey, int timeout, TimeUnit unit ) { return distributedLocker. lock (lockKey, unit, timeout); } /** * 尝试获取锁 * @param lockKey * @param waitTime 最多等待时间 * @param leaseTime 上锁后自动释放锁时间 * @return */ publicstaticboolean tryLock( String lockKey, int waitTime, int leaseTime) { return distributedLocker.tryLock(lockKey, TimeUnit .SECONDS, waitTime, leaseTime); } /** * 尝试获取锁 * @param lockKey * @param unit 时间单位 * @param waitTime 最多等待时间 * @param leaseTime 上锁后自动释放锁时间 * @return */ publicstaticboolean tryLock( String lockKey, TimeUnit unit, int waitTime, int leaseTime) { return distributedLocker.tryLock(lockKey, unit, waitTime, leaseTime); } /** * 获取计数器 * * @param name * @return */ publicstatic RCountDownLatch getCountDownLatch( String name){ return distributedLocker.getCountDownLatch(name); } /** * 获取信号量 * * @param name * @return */ publicstatic RSemaphore getSemaphore( String name){ return distributedLocker.getSemaphore(name); } } 底层封装 /** * @author gourd */ publicinterface DistributedLocker { RLock lock ( String lockKey); RLock lock ( String lockKey, int timeout); RLock lock ( String lockKey, TimeUnit unit, int timeout); boolean tryLock( String lockKey, TimeUnit unit, int waitTime, int leaseTime); void unlock( String lockKey); void unlock( RLock lock ); } /** * @author gourd */ @Component publicclass RedisDistributedLocker implements DistributedLocker { @Autowired private RedissonClient redissonClient; @Override public RLock lock ( String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock . lock (); returnlock ; } @Override public RLock lock ( String lockKey, int leaseTime) { RLock lock = redissonClient.getLock(lockKey); lock . lock (leaseTime, TimeUnit .SECONDS); returnlock ; } @Override public RLock lock ( String lockKey, TimeUnit unit , int timeout) { RLock lock = redissonClient.getLock(lockKey); lock . lock (timeout, unit); returnlock ; } @Override publicboolean tryLock( String lockKey, TimeUnit unit, int waitTime, int leaseTime) { RLock lock = redissonClient.getLock(lockKey); try { returnlock .tryLock(waitTime, leaseTime, unit); } catch ( InterruptedException e) { returnfalse ; } } @Override publicvoid unlock( String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock .unlock(); } @Override publicvoid unlock( RLock lock ) { lock .unlock(); } } 测试