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

做网站吉林深圳谷歌优化seo

做网站吉林,深圳谷歌优化seo,asp.net 网站建设方案,网站建设方案合同redisson redisson如何来进行redis分布式锁实现的源码&#xff0c;基于redis实现各种各样的分布式锁的原理 https://redisson.org/ 这是官网 https://github.com/redisson/redisson/wiki/Table-of-Content 这是官方文档 开始 demo 建一个普通的工程在pom.xml里引入依赖 <…

redisson

redisson如何来进行redis分布式锁实现的源码,基于redis实现各种各样的分布式锁的原理
https://redisson.org/ 这是官网
https://github.com/redisson/redisson/wiki/Table-of-Content 这是官方文档

开始 demo

  • 建一个普通的工程
  • 在pom.xml里引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.8.1</version>
</dependency>  
  • 参照官网构建RedissonClient,同时看看对应的配置
    由于要在测试多节点,所以我再两台虚拟机,配置了一下redis cluster集群,标准的三主三从配置。
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://192.168.1.1:7001")
.addNodeAddress("redis://192.168.1.1:7002")
.addNodeAddress("redis://192.168.1.1:7003")
.addNodeAddress("redis://192.168.2.2:7001")
.addNodeAddress("redis://192.168.2.2:7002")
.addNodeAddress("redis://192.168.2.2:7003");RedissonClient redisson = Redisson.create(config);
  • 简单用一下分布式锁的功能
RLock lock = redisson.getLock("anyLock");
lock.lock();
lock.unlock();RMap<String, Object> map = redisson.getMap("anyMap");
map.put("foo", "bar");  map = redisson.getMap("anyMap");
System.out.println(map.get("foo"));  

getLock()

点进getLock方法,可以看到如下

@Override
public RLock getLock(String name) {
return new RedissonLock(connectionManager.getCommandExecutor(), name);
}

getLock()方法的时候,获取到的Lock对象是RedissonLock对象,就可以了,里面封装了一个ConnectionManager里获取的一个CommandExecutor,CommandExecutor是什么东西?
既然是Connection开头的,里面一定是封装了一个跟redis之间进行通信的一个Cconnection连接对象,CommandExecutor,命令执行器,封装了一个redis连接的命令执行器,可以执行一些set、get redis的一些操作,用来执行底层的redis命令的

RedissonLock

在这个RedissonLock的构造函数里面,建议大家关注的一行代码,别的没什么,主要是一个internalLockLeaseTime的东西,跟watchdog看门狗有关系的
我们在RedissonLock里面打几个断点
在这里插入图片描述
还有一个是lock()和unlock()方法,既然调用了,肯定要看一下
在这里插入图片描述

再往后走到这里,可以看到,在默认情况下,加锁的时候,long leaseTime, TimeUnit unit,是没有的,-1和null,就代表着说,只要你加到了一把锁,就一定会永久性的持有这把锁,除非是你当前持有这把锁的机器宕机了,watchdog看门狗就会发现,然后就会释放锁,避免说永久性的一个死锁发生

再去下面142行看看tryAcquire()做了什么
在这里插入图片描述
这个里面的方法tryLockInnerAsync() 这个是核心
在这里插入图片描述

tryLockInnerAsync() 加锁lua脚本

先仔细看看这里面的一块绿色代码,明显不是java,其实这就是redis的lua脚本
在这里插入图片描述
来分析一下
if (redis.call(‘exists’, KEYS[1]) == 0) then,KEYS[1]一看就是我们设置的那个锁的名字,人家先执行了redis的exists的指令,判断一下,如果“anyLock”这个key不存在,那么就进行加锁,实际加锁的指令
"redis.call(‘hset’, KEYS[1], ARGV[2], 1); " +
"redis.call(‘pexpire’, KEYS[1], ARGV[1]); " +
"return nil; " +
hset,redis的一个指令,相当于是在redis的一个map数据结构里设置一个key value
这个map对象的名字是我们传的anyLock,然后里面的k-v键值对,k我们假设为lockState,v值呢,设置为了1
hset KEYS[1] ARGV[2] 1 转换我们传的指令后就是 hset anyLock lockState 1

pexpire KEYS[1] ARGV[1],设置一个key的过期时间
KEYS[1]其实可以理解为就是我们设置的那个key,“anyLock”,ARGV[1]其实就是一个这个key的过期时间,可能是默认的一个值,叫做30000毫秒,30s,很有可能是说的是,这个anyLock这个key对应的过期时间就是30秒

再往下的逻辑"if (redis.call(‘hexists’, KEYS[1], ARGV[2]) == 1) then " +
"redis.call(‘hincrby’, KEYS[1], ARGV[2], 1); " +
"redis.call(‘pexpire’, KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
判断名字为anyLock的这个map对象里面某个k-v键值对,key键假设为lockState,他的对应值是不是1,(上面的逻辑中可以看到),如果存在的话就把这个值用命令hincrby +1
hincrby KEYS[1] ARGV[2] 1,将anyLock这个map中的lockState这个key的值累加1
pexpire’, KEYS[1], ARGV[1]是又把这个对象设置了一下过期时间
最后的return redis.call(‘pttl’, KEYS[1]); 是返回当前还有多久就过期了

那总结一下这个加锁逻辑,我们都知道 redis中的map数据结构是键值对。
那么这个加锁的时候,就是先判断 我们定义的锁名称“anyLock” 这个map结构是否存在,如果不存在的话,就加一个默认的键值对 k-v,key=某个默认值 value=1
如果这个名为“anyLock”的map结构已经存在了,就把那个默认的键值对k-v,key=某个默认值 value+1

commandExecutor.evalWriteAsync()

OK分析完脚本,再点进这个方法来看看
在这里插入图片描述
因为现在用的是redis cluster,3主3从的模式,那么这里就有是要把key放在其中某一个master上去。
这里的第一行int slot = connectionManager.calcSlot(key);
取出来redis cluster的数量,我们都知道,redis cluster集群的节点,默认是16384个,slot的数量默认就是16384个。
那这第一行的操作就是根据key的hash值,来计算出这个key要落到应该要哪个slot节点上

下一行代码就很明显了,是根据slot节点获取到,这个slot是放在哪个master上的?
在这里插入图片描述
anyLock这个key,13434,算出来是这个slot,相当于是针对“anyLock”这个key计算出来一个hash值,然后将这个hash值对16384这个slot数量进行取模,int slot = connectionManager.calcSlot(key);
取模之后就可以拿到当前这个“anyLock”的key对应的是哪个slot
在这里插入图片描述
再回到getNodeSource()方法中看看MasterSlaveEntry
MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=1, freeSubscribeConnectionsCounter=50, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://192.168.1.1:7002], nodeType=MASTER, firstFail=0]]

redis://192.168.1.1:7002,编号为13434的slot所在的master是这台机器的这个端口对应的master实例
此时就是已经知道了,其实必须是将加锁的那段lua脚本,放到redis://192.168.1.1:7002这个master实例上去执行,完成加锁的操作

回过头看一下这里的代码
这里的逻辑很简单了,里面也没必要再去跟的很深了,这里大概就是上面我们分析的,拿着刚才生成的lua脚本去对应的master节点中执行脚本,把数据存入。
在这里插入图片描述
在这里插入图片描述

总结

总结一下,这里就是最基础的通过lua脚本加锁的逻辑,我们知道了redis加锁的时候是通过lua脚本将其传到redis中来加锁的。加锁的时候本质上就是新建了一个map类型的数据,key是我们的锁名称。

流程:

  • 判断key是否存在
    • 不存在的话新建一个map类型的数据,数据名称为锁名称
    • map中的数据只有一对k-v,key应该为加锁次数,默认value为1,这个主要用来做同一个线程多次加锁的重入操作
    • pexpire 命令设置过期时间,默认为30000ms 也就是30s
  • 存在的话
    • hincrby 命令,将map中的加锁次数 +1
    • pexpire 再次将过期时间设置为30000ms 也就是30s
  • pttl命令,返回当前数据的过期时间
http://www.15wanjia.com/news/36395.html

相关文章:

  • 网站推广工作流程图广州百度seo
  • sketch做网站线框图爱站网官网查询域名
  • 企业定制网站价格表自媒体发布平台有哪些
  • 短视频运营推广36优化大师下载安装
  • 网站链接怎么做二维码百度投诉中心24人工客服
  • 如何进入网站后台地址seo北京网站推广
  • 淄博网站建设公司推荐白酒最有效的推广方式
  • 黄江镇做网站百度seo是什么意思
  • php和网站开发如何自己做一个网址
  • 工业设计作品集欣赏上海百度提升优化
  • 泰兴做网站360优化大师下载安装
  • 无锡网站推广企业网站seo服务
  • 南京营销型网站建设谷歌seo和百度seo
  • 集团网站建设思路北京网站seo
  • 做网站python和php刷死粉网站推广
  • 简述设计web站点的一般步骤什么是关键词搜索
  • 做母婴用品的网站有哪些新浪微舆情大数据平台
  • 最好的赣州网站建设浑江区关键词seo排名优化
  • 单位有公网ip怎么做网站净水器十大品牌
  • 宁波北京网站建设深圳网站设计三把火
  • 河北省邢台市seo山西seo推广
  • 在网站做网管工作都做什么聚合搜索引擎接口
  • 微信网站欣赏成都多享网站建设公司
  • 三门峡做网站优化什么是seo教程
  • 苏州推荐网络公司建网站济南seo关键词排名工具
  • wordpress 上传 阿里云网站怎么优化关键词排名
  • 定远建设局官方网站推荐就业的培训机构
  • 有了源代码怎么做网站seo查询源码
  • vip视频解析网站怎么做的网站结构有哪几种
  • 查网站是不是用shopify做的怎么在百度做网站推广