• 【分布式锁】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);
        }
    }
  • 相关阅读:
    openresty开发系列35--openresty执行流程之5内容content阶段
    openresty开发系列34--openresty执行流程之4访问阶段
    openresty开发系列33--openresty执行流程之3重写rewrite和重定向
    [转] Dangers of using dlsym() with RTLD_NEXT
    fork failed because of Out Of Memory
    gdb 拾穗
    原子变量的性能问题
    blktrace + blkparse + btt 分析IO
    [转] 利用BLKTRACE分析IO性能
    使用perf + FlameGraph生成进程火焰图
  • 原文地址:https://www.cnblogs.com/zhaww/p/14047835.html
Copyright © 2020-2023  润新知