【分布式锁思想集合】

微服务分布式锁思想集合

  1. 基于扣减库存演示超卖,使用分布式锁解决这种超卖的情况
  2. 使用nginx做负载均衡、使用jmeter做压力测试
  3. 环境要求:jdk1.8+、maven3.x
  4. 技术要求:SpringBoot2.x、Springmvc、spring、mybatis、springData-redis、mysql、
    redis
  5. 开发工具:idea、nginx、jmeter
  6. 其他: zookeeper、lua脚本等

1. 传统锁

JVM本地锁(synchronized、ReentrantLock)

2.基于redis的分布式锁

redis乐观锁

  • 手写实现
    • 基本实现
    • 防死锁
    • 防误删
    • 可重入
    • 可续期
    • 红锁算法
  • Redisson框架
    • 可重入锁及源码分析
    • 公平锁FairLock
    • 联锁、红锁
    • 读写锁
    • 信号量
    • 闭锁

3.基于zk的分布式锁

  • 手写实现
    • Zookeeper的安装
    • 常用指令及Java客户端
    • 基本实现分布式锁
    • 实现阻塞锁
    • 实现可重入式分布式锁
  • Curator框架
    • 可重入锁及源码解读
    • 可重入的读写锁
    • 信号量
    • 栅栏
    • 共享计数器

4.基于mysql的分布式锁

一句sql扣减库存

update stock set count = count -1 where product_code = '1001' and count >= 1

这个update语句会自动加锁,这是靠数据库引擎的(表锁)

优点:

  1. 数据库引擎加锁执行更新保证了服务集群不会出现超卖现象
  2. 吞吐量也会很高

缺点:

  1. 锁范围的问题(表锁、行锁)
  2. 同一商品有多条库存记录
  3. 无法记录库存变化前后的状态

Mysql悲观锁:

select ... for update

  1. 查询并锁定信息
java 复制代码
@select("select * from db_stock where product_code = #{productCode} for update")
List<Stock> queryStock(String productCode);
List<Stock> stocks = this.stockMapper.queryStock("1001");
Stock stock = stocks.get(0);
  1. 判断库存充足
java 复制代码
if(stock != null && stock.getCount >0) {
   stock.setCount(stock.getCount -1);
   this.stockMapper.updateById(stock);
}
  1. 扣减库存
    配和事务注解@Transational

4.1 mysql悲观锁中使用行级锁

python 复制代码
# 1.锁的查询或者更新条件必须是索引字段
# 2.查询或更新条件必须是具体值(可以是in,= 但不能是!=,like)

4.2 mysql

java 复制代码
/*
1. jvm本地锁:三种情况导致锁失效 600
	多例模式
	事务 Read Uncommitted
	集群部署
2. 一个sql语句:更新数量时判断 2000
	解决:三个锁失效
	问题:
		1. 锁范围问题 表级锁 行级锁
		2. 同一个商品有多条库存记录
		3. 无法记录库存变化前后的状态
3. 悲观锁:select ... for update 
	问题:
		1. 性能问题
		2. 死锁问题:对多条数据加锁时,加锁数据一致。
			①事务,对第一条数据加锁,请求第二条数据的锁;
			②事务,对第二天数据加锁,请求第一条数据的锁;
			两个事务争抢对方的锁,造成死锁问题。
		3. 库存操作要统一:select..for update  普通的select
4. 乐观锁:时间戳 version版本号 CAS机制
	问题:
		1.高并发情况下,性能极低
		2.ABA问题
		3.读写分离情况下乐观锁不可靠(主从数据库 数据拷贝的原因)
总结:
	性能:一个sql > 悲观锁 > jvm锁 > 乐观锁
	如果追求极致性能,业务场景简单并且不需要记录数据变化前后的情况下:
		优先选择:一个sql
	如果写并发量较低(多读),争抢不是很激烈的情况下优先选择:乐观锁
	如果写并发量较高,一般会经常冲突,此时选择乐观锁的话,会导致业务代码不间断的重试。
		优先选择:mysql悲观锁
	不推荐jvm本地锁。
*/
相关推荐
Wang's Blog1 小时前
RabbitMQ: 消息中间件技术选型
分布式·rabbitmq
古城小栈10 小时前
.proto文件:跨语言通信 的 协议基石
分布式·微服务
song50112 小时前
鸿蒙 Flutter 日志系统:分级日志与鸿蒙 Hilog 集成
图像处理·人工智能·分布式·flutter·华为
Wang's Blog12 小时前
RabbitMQ:消息可靠性保障之消费端 ACK 机制与限流策略解析
分布式·rabbitmq
松☆12 小时前
深入实战:Flutter + OpenHarmony 分布式软总线通信完整实现指南
分布式·flutter
武子康13 小时前
Java-194 RabbitMQ 分布式通信怎么选:SOA/Dubbo、微服务 OpenFeign、同步重试与 MQ 异步可靠性落地
大数据·分布式·微服务·消息队列·rabbitmq·dubbo·异步
song50113 小时前
鸿蒙 Flutter 插件测试:多版本兼容性自动化测试
人工智能·分布式·flutter·华为·开源鸿蒙
韩凡13 小时前
JAVA微服务与分布式(概念版)
java·分布式·微服务
电气铺二表姐1377441661513 小时前
从并网到离网,尽在掌握:分布式储能微网智能监控与能量管理系统
运维·分布式·物联网·能源
L、21814 小时前
Flutter + OpenHarmony 分布式能力融合:实现跨设备 UI 共享与协同控制(终极篇)
javascript·分布式·flutter·ui·智能手机·harmonyos