Redis分布式锁之redisson
常用的redis解决方案:
redisson实现分布式锁原理:
- 线程首先会尝试获取锁,如果获取锁成功,会执行加锁操作并执行业务代码,如果没有成功会使用自旋锁方式不断尝试获取锁
- redisson为防止死锁方式默认加锁时间为30s,看门狗过30秒查看是否依然持有锁,如果持有会延长时间,当业务执行完毕释放锁
1.maven依赖
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.8.0</version> </dependency>
2.spring注入客户端
package com.violet.sys.configuration; 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; /** * @Description //TODO * @Date 2020/3/19 22:32 * @Author huangwb **/ @Configuration public class RedissonAutoConfiguration { @Value("${redisson.addres}") private String addressUrl; @Value("${redisson.password}") private String password; /** * @return org.redisson.api.RedissonClient * @Author huangwb * @Description //TODO 单机模式配置 * @Date 2020/3/19 22:54 * @Param [] **/ @Bean public RedissonClient getRedisson() { Config config = new Config(); config.useSingleServer() .setAddress(addressUrl).setPassword(password) .setRetryInterval(50000) .setTimeout(100000) .setConnectTimeout(100000); return Redisson.create(config); } }
3对应的yml配置
redisson:
addres: redis://127.0.0.1:6379
password: 你的reids密码
4.业务逻辑代码
4.1看门狗自动检测锁
这样的代码会出现一个看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期,没过10s检测一遍,通过config.setLockWatchdogTimeout(“时间”)可以设置超时时间
package com.violet.sys.controller; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; 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.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * TODO(描述) * * @author violet * @Title ReidsLock * @Description: * @date 2020/7/8 15:17 */ @RestController @Api(tags={"分布式锁"}) public class ReidsLock { private Logger logger = LoggerFactory.getLogger(ReidsLock.class); @Autowired RedissonClient redissonClient; @RequestMapping(value = "redislock", method = RequestMethod.POST) @ApiOperation(value = "测试分布式锁", notes = "接口描述", httpMethod = "POST") @ApiOperationSupport(author = "violet") public void redislock(){ //你锁的id String key = "dec_store_lock" ; //1、获取一把锁,只要锁的名字一样,就是同一把锁 RLock lock = redissonClient.getLock(key); lock.lock(); int i =0; logger.info(i+": 获取锁"); try { logger.info(i+": 打印锁"); logger.info(String.valueOf(i)); i++; } catch (Exception e) { System.out.println(e.getMessage()); } finally { //解锁 lock.unlock(); } } }
4.2 自行设置锁超时时间
// 加锁以后10秒钟自动解锁,不会续期 // 无需调用unlock方法手动解锁 //10秒自动解锁,自动解锁时间一定要大于业务的执行时间。 lock.lock(10, TimeUnit.SECONDS); // 尝试加锁,最多等待100秒,超出不等,上锁以后10秒自动解锁 boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { ... } finally { lock.unlock(); } }
4.3设置公平锁
RLock fairLock = redisson.getFairLock("dec_store_lock"); // 最常见的使用方法 fairLock.lock(); // 10秒钟以后自动解锁 // 无需调用unlock方法手动解锁 fairLock.lock(10, TimeUnit.SECONDS); // 尝试加锁,最多等待100秒,上锁以后10秒自动解锁 boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS); ... fairLock.unlock();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
``
接下来就可以用jmeter压测了,我这里就不贴图了