博客
关于我
Redisson实现分布式锁(3)—项目落地实现
阅读量:447 次
发布时间:2019-03-06

本文共 2508 字,大约阅读时间需要 8 分钟。

Redisson 实现分布式锁(3)——项目落地实现


项目概述

技术架构

本项目基于以下技术栈实现:

  • SpringBoot 2.1.5:用于快速构建微服务型应用
  • Maven 3.5.4:依赖管理工具,确保依赖版本一致性
  • Redisson 3.5.4:高级 Redis 客户端,支持分布式锁
  • Lombok 插件:简化 Java 代码编写

加锁方式

本项目支持两种加锁模式:

  • 自定义注解加锁

    通过注解方式轻松实现分布式锁:

    @DistributedLock(value = "goods", leaseTime = 5)  public String lockDecreaseStock() {      // 业务逻辑  }
  • 常规加锁

    直接调用 RedissonLock API:

    // 1、加锁  redissonLock.lock("redisson", 10);  // 2、业务逻辑  // 3、解锁  redissonLock.unlock("redisson");
  • Redis 部署方式

    支持四种 Redis 部署模式:

  • 单机模式部署
  • 集群模式部署
  • 主从模式部署
  • 哨兵模式部署
  • 仅需修改 application.properties 配置文件即可切换部署方式,无需代码修改。

    项目整体结构

    项目模块划分清晰:

    • redis-distributed-lock-core:核心实现模块,包含以下功能:
      • 注解锁核心逻辑
      • Redis 连接管理
      • 锁策略实现(单机、集群等)
    • redis-distributed-lock-web-test:测试模块
      • 测试基于注解的分布式锁
      • 测试基于常规的分布式锁

    测试

    通过模拟 1 秒内 100 个线程请求接口,测试分布式锁的性能和正确性。

    lock 锁测试

    public static volatile Integer TOTAL = 10;@GetMapping("lock-decrease-stock")  public String lockDecreaseStock() throws InterruptedException {    redissonLock.lock("lock", 10);    if (TOTAL > 0) {        TOTAL--;    }    Thread.sleep(50);    // 检查当前线程是否持有锁      if (redissonLock.isHeldByCurrentThread("lock")) {        redissonLock.unlock("lock");    }    return "库存减少成功";}

    测试结果显示,lock 锁在高并发场景下表现稳定,避免了超卖问题。

    trylock 锁测试

    public static volatile Integer TOTAL = 10;@GetMapping("trylock-decrease-stock")  public String trylockDecreaseStock() throws InterruptedException {    if (redissonLock.tryLock("trylock", 10, 5)) {        if (TOTAL > 0) {            TOTAL--;        }        Thread.sleep(50);        redissonLock.unlock("trylock");        return "库存减少成功";    } else {        log.warn("[ExecutorRedisson] 获取锁失败");        return "未能获取锁";    }}

    trylock 锁在部分场景下可能导致库存减少操作跳过,但通过合理设置超时时间可以避免。

    注解锁测试

    public static volatile Integer TOTAL = 10;@GetMapping("annotatin-lock-decrease-stock")  @DistributedLock(value = "goods", leaseTime = 5)  public String lockDecreaseStock() throws InterruptedException {    if (TOTAL > 0) {        TOTAL--;    }    return "库存减少成功";}

    注解锁适用于方法级锁管理,粒度较大,适合分布式场景。


    三、锁的选择

    观点

    lock 锁是最优选择,因为其性能更优且更安全。

    lock 与 trylock 性能对比

    通过模拟 5 秒内 1000 个线程压测,得出以下结果:

    • lock 锁:平均响应时间 31324 ms,吞吐量 14.7/sec
    • trylock 锁:平均响应时间 28628 ms,吞吐量 16.1/sec

    trylock 锁在单次测试中表现优于 lock 锁,但从长期性能来看,lock 锁更稳定。

    常见异常

    在使用 RedissonLock 时,可能会遇到以下异常:

    redissonLock.lock("redisson", 1);// 业务逻辑需要 2 秒redissonLock.release("redisson");

    原因分析:线程 1 获得锁后,业务逻辑执行 1 秒后锁自动过期,线程 2 获得锁。线程 1 调用 release 时,由于锁不再由当前线程持有,会抛出异常。

    解决方案:合理设置锁过期时间,避免过短导致异常。可以通过 isHeldByCurrentThread 方法判断当前线程是否持有锁。


    参考

  • Redisson 官方文档
  • 分布式锁设计模式
  • RedissonLock 实现细节

  • 本文通过实际项目实现和测试,总结了 Redisson 实现分布式锁的经验与教训,希望对开发者有所帮助。如果内容对您有价值,请给予支持!

    转载地址:http://jvffz.baihongyu.com/

    你可能感兴趣的文章
    php7,从phpExcel升级到PhpSpreadsheet
    查看>>
    PHP8中match新语句的操作方法
    查看>>
    PHP:第一章——PHP中常量和预定义常量
    查看>>
    PHP:第一章——PHP中的位运算
    查看>>
    phpcms
    查看>>
    phpcms 2008 product.php pagesize参数代码注射漏洞
    查看>>
    phpcms V9 自定义添加 全局变量{DIY_PATH}方法
    查看>>
    Redis五种核心数据结构的基本使用与应用场景
    查看>>
    PHPCMS多文件上传和上传数量限制
    查看>>
    phpEnv的PHP集成环境
    查看>>
    PHPExcel一些基本设置总结
    查看>>
    PHPExcel导入导出 若在thinkPHP3.2中使用(无论实例还是静态调用(如new classname或classname::function)都必须加反斜杠,因3.2就命名空间,如/c...
    查看>>
    PHPMailer发送邮件
    查看>>
    phpmailer发送邮件,可以带附件
    查看>>
    phpmyadmin 安装
    查看>>
    phpmyadmin数据库建表及插入
    查看>>
    phprpc简单使用
    查看>>
    phpstorm 2016.3.3 激活
    查看>>
    phpstorm中Xdebug的使用
    查看>>
    phpstorm中使用svn版本控制器
    查看>>