【分布式锁】SpringBoot中使用Redisson

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);
    }
}
原文地址:https://www.cnblogs.com/zhaww/p/14047835.html