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

船员专用网站开发建议淘宝上有做网站的吗

船员专用网站开发建议,淘宝上有做网站的吗,宁波网站建设制作,如何运行asp.net网站一、使用Redisson步骤 Redisson各个锁基本所用Redisson各个锁基本所用Redisson各个锁基本所用 二、源码解析 lock锁 1#xff09; 基本思想#xff1a; lock有两种方法 一种是空参 另一种是带参 * 空参方法#xff1a;会默认调用看门狗的过期时间30*1000…一、使用Redisson步骤 Redisson各个锁基本所用Redisson各个锁基本所用Redisson各个锁基本所用 二、源码解析 lock锁 1 基本思想 lock有两种方法 一种是空参  另一种是带参          * 空参方法会默认调用看门狗的过期时间30*100030秒          * 然后在正常运行的时候会启用定时任务调用重置时间的方法间隔为开门看配置的默认过期时间的三分之一也就是10秒          * 当出现错误的时候就会停止续期直到到期释放锁或手动释放锁          * 带参方法手动设置解锁时间到期后自动解锁或者业务完成后手动解锁不会自动续期 源码 Lock 调用lockInterruptibly()方法会默认传入lease 为-1该值再后面起作用 public void lockInterruptibly(long leaseTime, TimeUnit unit) throws InterruptedException {long threadId Thread.currentThread().getId();//获取该锁的过期时间如果该锁没被持有会返回一个null如果被持有 会返回一个过期时间Long ttl this.tryAcquire(leaseTime, unit, threadId);if (ttl ! null) {//ttl不为null说明锁已经被抢占了RFutureRedissonLockEntry future this.subscribe(threadId);this.commandExecutor.syncSubscription(future);try {//开始循环获取锁while(true) {//刚进如循环先尝试获取锁获取成功返回null跳出循环获取失败则继续往下走ttl this.tryAcquire(leaseTime, unit, threadId);if (ttl null) {return;}if (ttl 0L) {//如果过期时间大于0则调用getLatch// 返回一个信号量开始进入阻塞阻塞时长为上一次锁的剩余过期时长并且让出cup//有阻塞必然有唤醒位于解锁操作中this.getEntry(threadId).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS);} else {this.getEntry(threadId).getLatch().acquire();}}} finally {this.unsubscribe(future, threadId);}}} private T RFutureLong tryAcquireAsync(long leaseTime, TimeUnit unit, final long threadId) {//如果leaseTime -1即不等于默认值则表示手动设置了过期时间if (leaseTime ! -1L) {return this.tryLockInnerAsync(leaseTime, unit, threadId, RedisCommands.EVAL_LONG);} else {//如果leaseTime -1表示使用默认方式即使用看门狗默认实现自动续期RFutureLong ttlRemainingFuture this.tryLockInnerAsync(this.commandExecutor.getConnectionManager().getCfg().getLockWatchdogTimeout(), TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);ttlRemainingFuture.addListener(new FutureListenerLong() {public void operationComplete(FutureLong future) throws Exception {//如果tryLockInnerAsync执行成功if (future.isSuccess()) {//获取过期时间Long ttlRemaining (Long)future.getNow();//过期时间为空表示加锁成功if (ttlRemaining null) {//开启刷新重置过期时间步骤RedissonLock.this.scheduleExpirationRenewal(threadId);}}}});return ttlRemainingFuture;}} // lua脚本尝试抢占锁失败返回锁过期时间T RFutureT tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommandT command) {this.internalLockLeaseTime unit.toMillis(leaseTime);//直接使用lua脚本发起命令//通过lua脚本可以看出redisson加锁除了使用自定义的名字以外还要使用uuid// 加上当前线程的threadId组合以自定义名字作hash的key使用return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, command,//如果该锁未被占有则设置锁设置过期时间过期时间为 internalLockLeaseTime 然后返回nullif (redis.call(exists, KEYS[1]) 0) then redis.call(hset, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]);return nil; end; //如果锁已经被占有判断是否是重入锁如果是重入锁则将value增加1 代表重入并且设置过期时间返回null。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; //如果已经被站有所且不是重入锁则返回过期时间return redis.call(pttl, KEYS[1]);,Collections.singletonList(this.getName()), new Object[]{this.internalLockLeaseTime, this.getLockName(threadId)});} 看门狗续命 //看门狗续命机制private void scheduleExpirationRenewal(final long threadId) {//首先会判断该线程是否已经再重置时间的map中仅仅第一次进来是空的。if (!expirationRenewalMap.containsKey(this.getEntryName())) {//使用了看门狗默认的时间30秒 除以3 也就是延迟10秒后执行Timeout task this.commandExecutor.getConnectionManager().newTimeout(new TimerTask() {public void run(Timeout timeout) throws Exception {//判断是否该线程是否还持有锁如果持有返回1并且设置过期时间如果没持有返回0RFutureBoolean future RedissonLock.this.commandExecutor.evalWriteAsync(RedissonLock.this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(pexpire, KEYS[1], ARGV[1]); return 1; end; return 0;,Collections.singletonList(RedissonLock.this.getName()), new Object[]{RedissonLock.this.internalLockLeaseTime, RedissonLock.this.getLockName(threadId)});future.addListener(new FutureListenerBoolean() {public void operationComplete(FutureBoolean future) throws Exception {//从map中移除该线程这样下次再调用该方法仍然可以执行RedissonLock.expirationRenewalMap.remove(RedissonLock.this.getEntryName());if (!future.isSuccess()) {RedissonLock.log.error(Cant update lock RedissonLock.this.getName() expiration, future.cause());} else {if ((Boolean)future.getNow()) {//当lua脚本返回1表是true也就是仍然持有锁则递归调用该方法RedissonLock.this.scheduleExpirationRenewal(threadId);}}}});}}, this.internalLockLeaseTime / 3L, TimeUnit.MILLISECONDS);if (expirationRenewalMap.putIfAbsent(this.getEntryName(), task) ! null) {task.cancel();}}}2、unlock 源码 public RFutureVoid unlockAsync(final long threadId) {final RPromiseVoid result new RedissonPromise();//调用lua脚本释放锁RFutureBoolean future this.unlockInnerAsync(threadId);future.addListener(new FutureListenerBoolean() {public void operationComplete(FutureBoolean future) throws Exception {if (!future.isSuccess()) {result.tryFailure(future.cause());} else {Boolean opStatus (Boolean)future.getNow();//如果锁状态为null表示存在异常为正常释放锁之前被别人占领锁了if (opStatus null) {IllegalMonitorStateException cause new IllegalMonitorStateException(attempt to unlock lock, not locked by current thread by node id: RedissonLock.this.id thread-id: threadId);result.tryFailure(cause);} else {//如果返回0.为false 表示可重入锁不取消重置过期时间//返回1 为true表示已解锁取消重置过期时间if (opStatus) {RedissonLock.this.cancelExpirationRenewal();}//解锁result.trySuccess((Object)null);}}}});return result;}protected RFutureBoolean unlockInnerAsync(long threadId) {return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,//当key不存在表示锁未被持有说明不用解锁了返回1 1在后续表示取消重置过期时间if (redis.call(exists, KEYS[1]) 0) then redis.call(publish, KEYS[2], ARGV[1]); return 1; end; //key存在但是持有锁的线程不是当前线程返回null后面会提出一个异常if (redis.call(hexists, KEYS[1], ARGV[3]) 0) then return nil;end; //锁状态-1后仍然大于0表示可重入锁仍处于锁定状态返回00在后续表示 不做处理仍然重置过期时间local counter redis.call(hincrby, KEYS[1], ARGV[3], -1); if (counter 0) then redis.call(pexpire, KEYS[1], ARGV[2]); return 0; //返回锁状态不大于0正常解锁返回11在后续表示取消重置过期时间else redis.call(del, KEYS[1]); redis.call(publish, KEYS[2], ARGV[1]); return 1; end; return nil;, Arrays.asList(this.getName(), this.getChannelName()), new Object[]{LockPubSub.unlockMessage, this.internalLockLeaseTime, this.getLockName(threadId)});}三、集群环境下潜在问题 在Redis主从架构哨兵模式的环境下业务系统已经成功获取了锁redis写入数据但是正要往从库上存数据时发生主库宕机的情况从库在哨兵的选举下成为了主库而另外一个业务请求再次需要获取锁会直接访问到新的主库而此时新主库是没有锁信息的此时就会出现业务重复的情况。
http://www.hkea.cn/news/14379455/

相关文章:

  • 奇缦科技珠海网站建设优化大庆市工程建设信息去哪个网站
  • 在线购物网站功能模块上海制作网站公司
  • 新乡网站建设哪家好网络技术服务
  • 刚做的网站适合做外链吗体现网站特色
  • 安徽省住房和城乡建设厅官方网站衡水网站联系电话
  • 番禺人才网官方网站信息公布烟台品牌网站建设
  • 徐州建站公司模板遵义网吧
  • 有路由器做网站公司字号大全
  • 户外运动网站建设策划如何介绍一个网站的促销功能
  • 编写 网站 语言济南学习做网站
  • 网站外链怎么做收银系统一套多少钱
  • app与网站网络维护协议
  • 什么情况下网站需要备案互联网电商
  • 中国建设银行青岛分行网站长春南京小学网站建设
  • 360网站弹窗推广怎么做的小程序注册哪类商标
  • 做展柜在哪些网站找客户wordpress 查看大图
  • 学习建设网站wordpress 文章不同背景图片
  • 网站建设千套素材制作企业网站的目的
  • 网站维护难做南阳网站建设南阳
  • 网站建设公司赚钱app怎么制作多少钱
  • 长沙网站建设设计扎染毕业设计代做网站
  • wordpress页面变量seo实战密码第三版pdf下载
  • 网站建设和网站推广可以同一家做吗济宁高端网站建设
  • 空间业务建设网站合击版手游带月灵
  • 广州站三维家官网在线设计
  • 平凉市建设局门户网站做水果网站用什么域名
  • 重庆网站建设就选承越免费注册邮箱帐号
  • 网站关键词连接符门户网站网页设计规范
  • wordpress 布局块调整广东seo推广多少钱
  • 网站建设哈尔滨seo技术外包公司