文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

三种方法+三种选型,用分布式锁还怕啥并发问题呀?

2024-12-02 00:23

关注

二、分布式锁介绍

1、什么是分布式锁

先了解一下什么是锁,在单机系统中,多个线程同时改变一个变量时,需要对变量或者代码块做同步从而保证串行修改变量,该同步实质上就是通过锁来实现。为了实现多个线程在同一个时刻针对同一块代码串行执行,就需要在某个地方做个标记,该标记必须每个线程都能看到,当标记不存在时可以设置该标记,其余后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记,此标记可以理解为锁。分布式锁就是在多机系统下的该标记。

2、实现分布式锁的主流方式

目前分布式锁的实现方式有3种主流方法,即:

1)基于数据库实现分布式锁,此处的数据库指的是MySQL关系型数据库;

2)基于缓存实现分布式锁,此处的缓存指的是Redis;

3)基于zookeeper/etcd实现分布式锁。

具体的关于锁的实现方式,已经有太多的文章进行介绍,本文就不再赘述。

三、质量保障

并发问题一旦涉及到钱,通常都会导致不同程度的资损,而且在我们的功能测试中是很难发现,因此对于并发的质量保障显得尤为的重要,可以抽象为3层来保障:事前、事中、事后三大步骤;事前保障通过Review 方式提前规避技术上的风险,事中保障验证在技术实现过程中是否存在漏洞,事后保障校验数据是否符合预期,对于有并发风险的项目上述三个步骤的保障缺一不可。

1、事前质量保障

事前保障的阶段发生在技术评审阶段,在此阶段,我们需要评估出当前业务场景下是否存在并发风险;如果存在,确定我们的技术选型。

1)评估并发风险

评估并发风险的关键点在于是否存在多个进程同时访问共享资源,简单来说是否存在多个进程在同一时间对同一个数据进行更新的操作;例如:电商中的库存,多人同时购买同一个商品,也就是会存在同一时间对同一个商品的库存进行更新,此处就存在并发风险。

2)技术选型

要做到正确的技术选型,我们就需要对上述3种方式实现的锁的优缺点以及应用场景需要进行了解。

MySQL数据库表的乐观锁适用于读多写少的场景且共享资源为数据库的单行数据;MySQL表锁实现的锁一般都不推荐使用;ZooKeeper分布式锁虽然适用于大部分分布式场景,但是由于其实现复杂度相对较高以及需要额外引入中间件,在大部分业务场景中的应用比较少,而基于Redis的缓存分布式锁应用较为广泛;但是具体业务实现采用哪种类型的分布式锁,还是需要基于当前的业务特性来进行决定;

在技术评审阶段,一方面我们要评估出是否存在并发风险,另外一方面,我们需要识别开发同学在技术的实现上可能存在的漏洞,针对分布式锁的实现漏洞可参考下文的CodeReview的关注点。

2、事中保障

1)CodeReview

① Redis缓存分布式锁

Redis通常可以使用setnx(key,value)函数来实现分布式锁。key和value就是基于缓存的分布式锁的两个属性,其中key表示锁id。setnx函数返回1表示获得锁,返回0表示其他服务器已经获得了锁;

Redis缓存分布式锁CodeReview注意点:

a. Redis Key

例如:商品库存,我们的key应该是具体到某个商品,而不是所有商品,锁住A商品,不会影响B商品。

b. 锁释放

针对上述问题,释放锁时需要先读取当前key的value,再和传入的value进行比较;上述是两个步骤一定要保证原子性,如果原生Redis可采用lua脚本保证原子性;如果tair,可采取TairString的cad方法;value必须是一个唯一值,唯一标记是当前对象加的锁。

c. 锁超时

可以再开启一个线程,为当前超时时间续时,但增加了系统的复杂度;

将过期时间设置非常长,一定能保证逻辑在锁释放之前能够执行完成;此方案简单但是有缺陷,当遇到系统突发异常时,锁无法被释放,只能等待redis key超时,而超时时间又设置的较长,因此在当前时间内谁都无法获取到锁,阻断业务执行,很有可能造成故障。

d. 锁粒度

如果针对某个共享资源的写是基于另外一个共享资源的值计算而来,那么锁的范围必须包含读共享资源;范围不包含读共享资源会导致脏读,最终导致数据的错误,如下图所示,Client B最终计算的B的结果就是错误的。

e. 获取锁失败

由于其他线程已经获取到了锁,当前线程获取锁失败后有3种处理方式:异常抛出让用户重试;通过自旋再次进行抢锁;发布订阅,订阅锁释放消息;在并发度低的场景下异常抛出以及自旋抢锁都可以,在高并发场景下异常抛出和自旋抢锁都不可取。

② MySQL数据库锁CR点

a. 数据库版本号乐观锁

在数据库的表中需要包含一个数字类型的字段version,读取数据时把version字段读出来,更新数据时判断当前version是否等于读取出来的version,并对当前version+1;如果等于就更新成功,不等于表示数据已过期更新失败。例如以积分体系为例,存在多种场景增加积分,通过乐观锁来保证数据的正确性。

乐观锁CR注意点:

b. 基于MySQL锁表

其实现原理是:创建一张锁表,对临界资源做唯一性约束,通过增加一条记录对某一资源上锁,释放锁时删除记录;一般不推荐此种用法。

2)并发测试

并发测试总体上可以分为3大类:

a. 复杂的并发场景,一次请求共享资源存在多个,且前后存在各种依赖关系,此种场      景适合于链路级别压测,压测模型需要精心设计。

b. 单一并发场景,一个共享资源,可以处理多次,例如:扣除某个商品的库存,可以       反复调用。

c. 单一并发场景,一个共享资源,且只能处理1次,例如:用户只有一次抽奖机会,        连续点2次会不会抽2次;

 public void invokeAllTask(ConcurrencyRequest request, Runnable task) {
final CountDownLatch startCountDownLatch = new CountDownLatch(1);
final CountDownLatch endCountDownLatch = new CountDownLatch(request.getConcurrency());
for (int i = 0; i < request.getConcurrency(); i++) {
Thread t = new Thread(() -> {
try {
startCountDownLatch.await();
try {
task.run();
} finally {
endCountDownLatch.countDown();
}
} catch (Exception ex) {
log.error("异常", ex);
}
});
t.start();
}
startCountDownLatch.countDown();
try {
endCountDownLatch.await();
} catch (InterruptedException ex) {
log.error("线程异常中断", ex);
}
}

3、事后保障

1)数据对账

数据对账(数据一致性校验)是我们在系统上线后对并发问题的最后一道防线,通过对账来识别我们的数据的不一致性问题;压测有成本,且受技巧熟练度和压测设计的影响,不一定能暴露问题;如果被测场景评估并发问题的发生概率极低,即使发生了影响也比较小,此时review+对账方式也不失为一种好的选择;

如何进行对账,不同的业务场景有不同的对账方法,例如:

select count(*)  as task_count,
scene_code,
order_id
from task_record
where unique_id is not null
group by scene_code,
order_id
having count(*)> 1

四、总结

作为质量保障同学一定要时刻绷着一根弦,当前场景下是否会存在并发问题;并发问题的识别简单而言就是是否存在同时更新同一个数据,如果是就一定要注意开发同学是否处理了并发,并发的实现主要是上面阐述的几种,然后按照场景进行分析即可;关于并发场景的质量保障,大体原则可以概括为如下:

来源:阿里开发者内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯