【分布式锁思想集合】

微服务分布式锁思想集合

  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本地锁。
*/
相关推荐
小王同学mf11 分钟前
Kafka生产者如何提高吞吐量?
分布式·kafka
songqq271 小时前
【快速入门】Kafka的安装部署
分布式·kafka
天冬忘忧1 小时前
Spark 中 RDD 的诞生:原理、操作与分区规则
大数据·分布式·spark
黄俊懿3 小时前
【架构师从入门到进阶】第一章:架构设计基础——第五节:架构演进(缓存到微服务)
分布式·后端·缓存·微服务·架构·系统架构·架构设计
songqq274 小时前
kafka面试夺命30问
分布式·面试·kafka
二进制杯莫停5 小时前
PaaS云原生:分布式集群中如何构建自动化压测工具
分布式·云原生·paas
不写是真记不住啊7 小时前
kafka生产消费问题
分布式·kafka
大数据编程之光8 小时前
【spark面试题】RDD容错机制
大数据·分布式·spark
lzhlizihang13 小时前
Kafka集群的安装与部署
大数据·分布式·kafka
小码哥呀13 小时前
RabbitMQ延迟队列(重要)
分布式·rabbitmq·ruby