type
status
date
slug
summary
tags
category
titleIcon
password
icon
calloutIcon
🎀
自定义分布式锁,解耦业务代码与通用锁管理部分。
节选自:

分布式锁,自定义AOP,Redisson,设计模式,SPEL

这一部分在视频里完全没提,第二版飞书文档的Day11里有部分讲解,以下做理论部分要点精简+代码部分分析。

分布式锁

  • 引入背景:Synchronized单机锁基于JVM的Monitor实现,在集群下多个JVM意味着多个Monitor,无法达到互斥的效果,需要在多个实例外设置同一把锁,即分布式锁。
  • Redis实现分布式锁的可能性:1.Redis可以被多JVM实例共享访问;2.SETNX互斥命令;3.DEL释放锁;4.单线程执行命令(串行)
  • Redis直接实现分布式锁与可能遇到的问题:
    • 直接实现:SET lock thread1 NX EX 20,主要包括两步
    • 1.超时释放:锁不一定正常释放(实例宕机),可导致死锁,需要设置过期时间(例中上锁与超时设置操作保持原子性)
    • 2.存入标识:存入自身线程标识,删除时如果仍是自身标识才可删除,防止锁误删(避免不了)(图源:
    • notion image
      notion image
      但判断与删除不是原子的,仍可能误删
      notion image
      超时释放难以避免锁误删,锁的操作需要原子性,主从同步存在延迟,同一线程无法多次获取同一锁可能死锁,所以需要解决:
    • 1.超时问题:WatchDog机制,锁成功开定时任务,锁到期前自动续期避免超时释放,同时宕机后一同停止,避免死锁
    • 2.原子性问题:Lua脚本
    • 3.锁重入:类似Synchronized,可使用Hash记录持有者与重入次数,次数0时删除
    • 4.主从同步延迟:RedLock
    • 5.锁失败重试
成熟解决方案:Redisson
 

Redisson Quick Start

maven引入

配置类与自动装配

ConditionalOnClass自动装配,引入Redisson依赖时配置才生效
入参的RedisProperties来源:
notion image
notion image
resources/META-INF/spring.factories:

基本使用

场景实例
  • waitTime:获取锁的等待时间。当获取锁失败后可以多次重试,直到waitTime时间耗尽。waitTime默认-1,即失败后立刻返回,不重试。
  • leaseTime:锁超时释放时间。默认是30,同时会利用WatchDog来不断更新超时时间。需要注意的是,如果手动设置leaseTime值,会导致WatchDog失效。
  • TimeUnit:时间单位

通用分布式锁AOP

避免通用的非业务代码对业务的侵入
通过注解标记切入点,同时传递锁参数(名称(解析SPEL表达式得到动态名);等待时间;超时时间;时间单位)

注解

切面

注:原代码里缺少了Ordered接口实现,可能会导致优先级跟@Transactional冲突,无法保证锁边界大于事务边界,这里代码补上,其中Orderded接口的getOrder方法用于获取AOP切面执行优先级(越小越优先),事务@Transactional的默认是Integer.MAX_VALUE(参见org.springframework.transaction.annotation.EnableTransactionManagement)
notion image
顺带一提,在org.springframework.context.annotation.ConfigurationClassUtils下也能见到类似的东西,不过是用于@Configuration配置类的
notion image

枚举

锁类型枚举(策略模式)
也可使用简单工厂模式(写法2)
EnumMap纯用数组实现,可能比HashMap更快
Implementation note: All basic operations execute in constant time. They are likely (though not guaranteed) to be faster than their HashMap counterparts.
实际上在业务里也有相关使用,优惠劵折扣策略里
锁失败策略(策略模式)
waitTime参数决定重试时间,没有不重试

业务AOP版本

防止兑换优惠劵业务超卖效果展示
  • 选择目标优惠劵
notion image
  • 设置jmeter参数
notion image
notion image
  • 运行结束,检查Redis 100条√ 1人1张√ 0剩余√
notion image
notion image
  • 检查数据库 100√
notion image
  • 检查汇总报告 √
notion image
  • 检查jmeter报告搜索仅100请求成功 √
notion image
  • 检查请求失败原因 优惠卷库存不足√ 请求超时(分布式锁获取超时)√
notion image
notion image
notion image
  • 与策略一致 √
notion image
代码:
领取优惠劵
notion image
notion image
兑换优惠劵
notion image
 
hexo主题Google搜索引擎收录流程天机学堂Day01复盘-环境搭建
Loading...
CamelliaV
CamelliaV
Java;CV;ACGN
最新发布
单例模式的四种写法
2025-4-24
体验MCP
2025-4-24
MetingJS使用自定义音乐源-CF+Huggingface部署
2025-4-2
博客访问站点测速分析与对比
2025-3-26
前端模块化
2025-3-16
Voxel2Mesh相关论文精读与代码复现
2025-3-15
公告
计划:
  • LLM相关
  • 支付业务 & 双token无感刷新
  • (线程池计算优惠方案)天机学堂Day09-Day12复盘-优惠劵业务
  • (业务复盘,技术汇总)天机学堂完结复盘
  • hot 100
 
2024-2025CamelliaV.

CamelliaV | Java;CV;ACGN