Redis分布式锁之redisson

常用的redis解决方案:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHt6m1O6-1601000482896)(C:\Users\VIolet\AppData\Roaming\Typora\typora-user-images\image-20200925095652120.png)]

redisson官网,官方讲解可以点击这里

redisson实现分布式锁原理:
  • 线程首先会尝试获取锁,如果获取锁成功,会执行加锁操作并执行业务代码,如果没有成功会使用自旋锁方式不断尝试获取锁
  • redisson为防止死锁方式默认加锁时间为30s,看门狗过30秒查看是否依然持有锁,如果持有会延长时间,当业务执行完毕释放锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c9VoOX50-1601000482899)(C:\Users\VIolet\AppData\Roaming\Typora\typora-user-images\image-20200925095835130.png)]

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压测了,我这里就不贴图了