【分布式锁思想集合】

微服务分布式锁思想集合

  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本地锁。
*/
相关推荐
小韩学长yyds3 小时前
从入门到精通:RabbitMQ的深度探索与实战应用
分布式·rabbitmq
问道飞鱼9 小时前
【分布式知识】Spring Cloud Gateway实现跨集群应用访问
分布式·eureka·gateway
Shinobi_Jack10 小时前
c#使用Confluent.Kafka实现生产者发送消息至kafka(远程连接kafka发送消息超时的解决 Local:Message timed out)
分布式·kafka
S-X-S11 小时前
RabbitMQ的消息可靠性保证
分布式·rabbitmq
小林想被监督学习15 小时前
RabbitMQ 在实际应用时要注意的问题
分布式·rabbitmq
S-X-S15 小时前
项目集成RabbitMQ
分布式·rabbitmq
DA022116 小时前
Win10系统部署RabbitMQ Server
分布式·rabbitmq
想做富婆21 小时前
大数据,Hadoop,HDFS的简单介绍
大数据·hadoop·分布式
霍格沃兹测试开发学社测试人社区21 小时前
软件测试丨消息管道(Kafka)测试体系
软件测试·分布式·测试开发·kafka