Redisson 是基于Redis实现的高性能的同步、加锁的的开源项目。
Redisson的开源地址,redisson-spring-boot-starter的开源地址。
笔者使用版本 3.14.0,快速上手。
1.1 添加 redisson-spring-boot-starter
maven dependency
<!-- redisson分布式锁 --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.14.0</version> </dependency>
1.2 如果是单机版本,只需要配置 redis 的配置就行了,其他什么都不用。
# redis 配置
spring: redis: port: 6379 host: 127.0.0.1 password: 000000 database: 0 timeout: 2000
1.3 测试一下是否有效。
package com.qs.monitor.controller.utils; import com.qs.monitor.common.JsonResult; import com.qs.monitor.controller.BaseController; import com.qs.monitor.service.UtilsService; import eu.bitwalker.useragentutils.Browser; import eu.bitwalker.useragentutils.OperatingSystem; import eu.bitwalker.useragentutils.UserAgent; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.concurrent.TimeUnit; /** * @author zhaww * @date 2020/9/24 * @Description . */ @RestController @RequestMapping("/utils") public class UtilsController extends BaseController {
// redisson 锁 @Resource private RedissonClient redissonClient; @RequestMapping(value = "test", method = RequestMethod.GET) public JsonResult test() { // test 为锁的主键,根据情况可使用 UUID RLock rLock = redissonClient.getLock("test"); System.out.println(Thread.currentThread().getName() + " 进入方法"); //如果锁已经被使用,则会一直在等着锁被释放 rLock.lock(); // 占用锁后,10秒后自动释放 // rLock.lock(10, TimeUnit.SECONDS); try { System.out.println(Thread.currentThread().getName() + " 开始执行"); Thread.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(Thread.currentThread().getName() + " 执行完成,解锁"); if (rLock.isLock()) {
rLock.unlock();
} } System.out.println(Thread.currentThread().getName() + " 返回结果"); return success(); } }
上面这种加锁方式,如果出现死锁,就所有的访问都无法进行了。所以推荐使用下面这种加锁方式!
package com.qs.monitor.controller.utils; import com.qs.monitor.common.JsonResult; import com.qs.monitor.controller.BaseController; import com.qs.monitor.service.UtilsService; import eu.bitwalker.useragentutils.Browser; import eu.bitwalker.useragentutils.OperatingSystem; import eu.bitwalker.useragentutils.UserAgent; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.concurrent.TimeUnit; /** * @author zhaww * @date 2020/9/24 * @Description . */ @RestController @RequestMapping("/utils") public class UtilsController extends BaseController { // redisson 锁 @Resource private RedissonClient redissonClient; @RequestMapping(value = "/test", method = RequestMethod.GET) public JsonResult test() { RLock rLock = redissonClient.getLock("test"); System.out.println(Thread.currentThread().getName() + " 进入方法"); Boolean isLock; try { //最多等待10秒拿锁,如果占用锁后,10秒后自动释放 isLock = rLock.tryLock(10,10, TimeUnit.SECONDS); if (isLock) { try { System.out.println(Thread.currentThread().getName() + " 开始执行"); Thread.sleep(8000); } finally { System.out.println(Thread.currentThread().getName() + " 执行完成,解锁"); if (rLock.isLocked()) { rLock.unlock(); } } } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 返回结果"); return null; } }
1.4 集群配置。(我尝试使用最新的文档中的配置方法,但是报 ymal 格式异常)所以只能自己重写配置类了
package com.qs.monitor.config; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import java.io.IOException; /** * @author zhaww * @date 2020/11/26 * @Description .Redisson配置信息 */ @Configuration public class RedissonConfig { /** * redis 地址 */ @Value("${spring.redis.redisson.address}") private String address; /** * 集群版配置 * @return */ @Bean RedissonClient redissonClusterConfig() { Config config = new Config(); //更多配置参考官网,不过多介绍 config.useClusterServers() .addNodeAddress(address) .addNodeAddress(address); return Redisson.create(config); } }