记者式问答:组长能给我讲讲分布式锁吗?

举报
赵KK日常技术记录 发表于 2023/06/30 23:43:16 2023/06/30
【摘要】 前几天不是整理那个字节跳动的问题么,整理到了分布式锁,自己看了看有点无感,趁着业务需要,就问了下组长,并解释了情景及解决办法。kk问:在忙吗?组长答:不忙,在看昨天的问题。kk问:我看**那业务那你写了个分布式锁,能讲下实现思路吗?组长答:那个啊,那都写了好久了,我看下...kk小声bb:我想问下咱们业务场景组长答:这个就是咱们业务线在**业务这,以前没有定时任务,拉取热数据的时候,防止多服...

前几天不是整理那个字节跳动的问题么,整理到了分布式锁,自己看了看有点无感,趁着业务需要,就问了下组长,并解释了情景及解决办法。

kk问:在忙吗?

组长答:不忙,在看昨天的问题。


kk问:我看**那业务那你写了个分布式锁,能讲下实现思路吗?

组长答:那个啊,那都写了好久了,我看下...


kk小声bb:我想问下咱们业务场景

组长答:这个就是咱们业务线在**业务这,以前没有定时任务,拉取热数据的时候,防止多服务拉取,出现重复调用什么的,情景很多,我先看下代码。


kk问:这个是基于redis实现的,但是我没看到哪里上锁啊?

组长答:这里么,大概思路就是先尝试获取下锁,

  1. 获取锁的时候,先判断能不能获取到锁,利用setNx,设置下k,v,超

时时间,如果返回1,就返回,因为K是唯一的么,这个判断即使多JVM线程进来,也是能够锁住的。

    2.如果没获取到锁,ttl(key)判断下锁是不是过期了,锁已经过期,则认为业务流程失败,或出现意外,需要释放锁,释放锁时判断是否过期,以及是否是自己的锁,get(key).qeuals(v),然后del(key)

    3.释放掉锁后,再加入新的锁。


kk问:这个我们传入的lock是啥啊?

组长答:这个我当时是用方法以及业务类型+时间戳的方式传进来的。


kk问:那这个超时时间呢?

组长答:这个不太好确定,因为你根据业务流程来看,有可能就是业务线响应慢,暂时没找到一个合适的超时时间。


kk问:那我不能在调用方法上加一个锁,使调用时串行化,或者用ReentryLock去加锁么?

组长答:你synchronized在多jvm下是无效的,单J锁在这种情况下都是失效的,现在分布式事务的话还是要用分布式锁,当然这个方法也存在很多问题。


kk问:什么情况会出现这个问题呢?

组长答:测试的时候,出现测试人员连点两下,极端情况下,一个线程打进来,进入A服务器进行获取,另一个线程进入B服务器获取,A获取到就返回了,B获取不到,就给释放了,不考虑redis崩的情况,后来让前端同学给按钮加了个禁用,点一次就让你等着就行了,然后测试拿着两台测试机,点一个页面后,在一分钟后又点了一下,效果和这个相同,就为了防止这种现象。


kk问:这种场景会有什么问题吗?

组长(mmp,问个没完了):第一步获取锁的时候没问题,但是当连个线程同时打进来,都没过期的话,多JVM,一个线程去unlock了,两一个就的在这等,等等等,然后业务线下层调用响应时间又长,很容易超时,前端就得等


kk问:响应慢的话有什么解决办法吗?

组长答:有一个DefaultRedisList的实现,底层是队列BlockingDeque,你可以看下实现结合redis做的。


kk问:能举个例子么?

组长答:比如我们**业务,放两个队列,一个用来接收请求,一个用来异步回调,放两个MQ里,try...catch   try  send(),然后异步callback,这样的话基本时没有延迟的,用户感知很低,一个就去发送,异步的去拉队列就行了


kk问:callback能用Http吗?

组长答:不行,只能是mq去推,你看下其他的实现方法吧,整体逻辑是没问题的,但是现在这个方法被弃用了。


kk问:为什么被弃用了啊?

组长答:开始我们是为了防止多端定时任务同时拉取热数据的,但后来我们给定时任务Quartz做了,他基于数据库做的分布式锁,有一个定时在拉,其他的就不去执行了,你可以看看Quartz的实现。总体我们处理分布式锁的逻辑没有问题,你可以看看其他人的实现方式。


kk:好的,基本是了解了,我再消化消化,自己看还是不够主观,对场景不是很了解。


分布式锁总结见博客。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。