当前位置: 首页 > news >正文

什么语言网站比较安全今日最新军事新闻

什么语言网站比较安全,今日最新军事新闻,外贸建站系统源码,上传自己做的网站分布式锁的实现有哪些? 1.Memcached分布式锁 利用Memcached的add命令。此命令是原子操作,只有在key不存在的情况下,才能add成功,也就意味着线程得到了锁。 2.Reids分布式锁 和Memcached的方式类似,利用Redis的setn…

image

image

image

image

image

image

image

image

分布式锁的实现有哪些?

1.Memcached分布式锁

利用Memcached的add命令。此命令是原子操作,只有在key不存在的情况下,才能add成功,也就意味着线程得到了锁。

2.Reids分布式锁

和Memcached的方式类似,利用Redis的setnx命令。此命令同样是原子性操作,只有在key不存在的情况下,才能set成功。(setnx命令并不完善,有替代方案)

3.Zookeeper分布式锁

利用Zookeeper的顺序临时节点,来实现分布式锁和等待队列。Zookeeper设计的初衷,就是为了实现分布式锁服务的。

4.Chubby

Google公司实现的粗粒度分布式锁服务,底层利用了Paxos一致性算法。

如何用Redis实现分布式锁?(以Redis为例)

分布式锁实现的三个核心要素:

1.加锁

最简单的方法是使用setnx命令。key是锁的唯一标识,按业务来决定命名。比如想要给一种商品的秒杀活动加锁,可以给key命名为“lock_sale_商品ID”。而value设置成什么呢?我们先设置为1。加锁的伪代码如下:

setnx(key,1)

当一个线程执行setnx返回1,说明key原本不存在,该线程成功得到了锁;当一个线程执行setnx返回0,说明key已经存在,该线程抢锁失败。

2.解锁

有加锁就有解锁。当得到锁的线程执行完任务,需要释放锁,以便其他线程进入。释放锁的最简单方式是执行del指令,伪代码如下:

del(key)

释放锁之后,其他线程就可以继续执行setnx命令来获得锁。

3.锁超时

如果一个得到锁的线程在执行任务的过程中挂掉,来不及显式地释放锁,这块资源将会永远被锁住,别的线程再也别想进来。

所以,setnx的key必须设置一个超时时间,以保证即使没有被显式释放,这把锁也要在一定的时间后自动释放。setnx不支持超时参数,所以需要额外的指令,伪代码如下:

expire(key,30)

综上所述,实现分布式锁的伪代码如下:

if(setnx(key,1) == 1){expire(key,30)try{do something...}finally{del(key)}
}

但是…这样会有其他问题吗?

image

上面的伪代码存在三个致命的问题:

1.setnx和expire的非原子性

设想一个极端场景,当某线程执行setnx,成功得到了锁:
image

setnx刚执行成功,还未来得及执行expire指令,节点1Duang的一声挂掉了

image

这样一来,这把锁就没有设置过期时间,变得“长生不老”,别的线程再也无法获得锁了。

如何解决?setnx指令本身是不支持传入超时时间的,幸好Redis2.6.12以上版本为set指令增加了可选参数,伪代码如下:

set(key,1,30,NX)

这样就可以取代setnx指令

2.del导致误删

又一个极端场景,假如某线程成功得到了锁,并且设置的超时时间是30秒。

image

如果某些原因导致线程B执行的很慢很慢,过了30秒都没执行完,这时候锁过期自动释放,线程B得到了锁。

image

随后,线程A执行完了任务,线程A接着执行del指令来释放锁。但这时候线程B还没执行完,线程A实际上删除的是线程B加的锁

image

如何避免这种情况呢?可以在del释放锁之前做一个判断,验证当前的锁是不是自己加的锁。

具体的实现,可以在加锁的时候把当前线程ID当做value,并在删除之前验证key的value是不是自己线程的ID。

加锁:

String threadId = Thread.currentThread().getId()
set(key,threadId,30,NX)

解锁:

if(threadId.equals(redisClient.get(key))){del(key)
}

但是这样做又隐含了一个新的问题,判断和释放锁是两个独立操作,不是原子性

所以这块可以用Lua脚本来实现:

String luaScript = 'if redis.call('get',KEYS[1]) == ARGV[1] then returnredis.call('del',KEYS[1]) else return 0 end';redisClient.eval(luaScript,Collections.singletonList(key),Collections.singltonList(threadId));

这样一来,验证和删除过程就是原子操作了。

3.出现并发的可能性

第二点的场景中,虽然我们避免了线程A误删掉key的情况,但是同一时间有A、B两个线程在访问代码块,仍然不完美。

如何解决呢?我们可以让获得锁的线程开启一个守护线程用来给快过期的锁“续航”

image

当过去了29秒,线程A还没有执行完,这时候守护线程会执行expire指令,为这把锁“续命”20秒,守护线程从第29秒开始,每20秒执行一次。

image

当线程A执行完任务,会显式关掉守护线程。

image

另一种情况,如果节点1忽然断电,由于线程A和守护线程在同一个进程,守护线程也会停下。这把锁到了超时的时候,没人给它续命,也就自动释放了。

image

http://www.hkea.cn/news/822445/

相关文章:

  • 优化好的网站做企业网站百度代理公司
  • 外贸b2c网站如何做推广百度电话人工服务
  • 百度怎样做网站并宣传网站2023上海又出现疫情了
  • wordpress后台登录慢阳山网站seo
  • 深圳网站建设企网络推广运营途径
  • 给自己女朋友做的网站yandex搜索引擎
  • 购物网站建设教程怎么在网上做广告宣传
  • 冠县做网站推广网站怎么制作
  • 开封 网站建设苹果被曝开发搜索引擎对标谷歌
  • 东莞虎门高铁站百度客户端电脑版下载
  • 建网站怎么挣钱的学seo推广
  • 自如网站做的好 服务哪个网站学seo是免费的
  • 国外网站阻止国内访问怎么做竞价推广工具
  • 建设一个网站需要哪些方面的开支百度人工客服
  • 品牌网站建设-建站之路最新疫情新闻100字
  • 东莞网站优化科技有限公司怀柔网站整站优化公司
  • 郑州网站建设联系方式外链是什么意思
  • 用wordpress做网站教程电脑优化大师有用吗
  • 佛山企业网站制作今日热点新闻事件
  • 企业网站网络推广黑帽seo培训
  • 欧美做的爱爱网站有哪些广告推广赚钱
  • 泉州网站建设工作室谷歌seo价格
  • 国建设委员会网站百度推广一天烧几千
  • 做网站 花园路国贸营销推广方案包括哪些内容
  • 做商城网站哪里买口碑营销属于什么营销
  • 鞋子 东莞网站建设真正的免费建站在这里
  • 网站上微信的链接怎么做项目平台
  • 做网站后有人抢注关键词网络营销方案策划论文
  • 苏州网站建设网站seo优化的方法
  • 设计网装修seo顾问服