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

东莞网站优化中易钢丝网片每平米价格

东莞网站优化中易,钢丝网片每平米价格,台州百度关键词优化,大专网页设计工资怎么样一、背景 网上redis分布式锁的工具方法#xff0c;大都满足互斥、防止死锁的特性#xff0c;有些工具方法会满足可重入特性。如果只满足上述3种特性会有哪些隐患呢#xff1f;redis分布式锁无法自动续期#xff0c;比如#xff0c;一个锁设置了1分钟超时释放#xff0c;…一、背景 网上redis分布式锁的工具方法大都满足互斥、防止死锁的特性有些工具方法会满足可重入特性。如果只满足上述3种特性会有哪些隐患呢redis分布式锁无法自动续期比如一个锁设置了1分钟超时释放如果拿到这个锁的线程在一分钟内没有执行完毕那么这个锁就会被其他线程拿到可能会导致严重的线上问题。 既然存在锁过期而任务未执行完毕的情况那是否有一种可以在任务未完成时自动续期的机制呢几年前在redisson中找到了看门狗的自动续期机制就是解决这种分布式锁自动续期的问题的。 Redisson 锁的加锁机制如上图所示线程去获取锁获取成功则执行lua脚本保存数据到redis数据库。如果获取失败: 一直通过while循环尝试获取锁(可自定义等待时间超时后返回失败)获取成功后执行lua脚本保存数据到redis数据库。Redisson提供的分布式锁是支持锁自动续期的也就是说如果线程仍旧没有执行完那么redisson会自动给redis中的目标key延长超时时间这在Redisson中称之为 Watch Dog 机制 二、redisson 看门狗使用以及原理 1.redisson配置和初始化 pom.xml dependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.16.4/version /dependencyapplication.yaml redis:host: xxxxxxxpassword: xxxxxxmax-active: 8max-idle: 500max-wait: 1min-idle: 0port: 6379timeout: 1000msdatabase: 0redisson配置类 Configuration public class RedisConfig {//最简单的redisson初始化配置Beanpublic RedissonClient getRedisson() {Config config new Config();config.useSingleServer().setAddress(redis:// host : port).setPassword(password);return Redisson.create(config);} }2.redisson看门狗使用 使用redisson分布式锁的目的主要是防止分布式应用产生的并发问题所以一般会进行一下调整改为AOP形式去进行业务代码解耦。这里会加入自定义注解和AOP。 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RedisLock {//锁的名称String lockName();//锁的失效时间long leaseTime() default 3;//是否开启看门狗默认开启开启时锁的失效时间不执行。任务未完成时会自动续期锁时间//使用看门狗锁默认redis失效时间未30秒。失效时间剩余1/3时进行续期判断是否需要续期boolean watchdog() default true; }public class RedisLockAspect {Autowiredprivate RedissonClient redissonClient;private static final String REDIS_PREFIX redisson_lock:;Around(annotation(redisLock))public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {String lockName redisLock.lockName();RLock rLock redissonClient.getLock(REDIS_PREFIX lockName);Object result null;boolean isLock;if(redisLock.watchdog()){isLock rLock.tryLock(0, TimeUnit.SECONDS);}else {isLock rLock.tryLock(0,redisLock.leaseTime(), TimeUnit.SECONDS);}if(isLock){try {//执行方法result joinPoint.proceed();} finally {if (rLock.isLocked() rLock.isHeldByCurrentThread()) {rLock.unlock();}}}else {log.warn(The lock has been taken:{},REDIS_PREFIX lockName);}return result;} }Scheduled(cron */10 * * * * ?)//使用注解进行加锁RedisLock(lockName npa_lock_test,watchdog true)public void redisLockTest() {System.out.println(get lock and perform a task);try {Thread.sleep(20000L);} catch (InterruptedException e) {e.printStackTrace();}}这里使用定时任务进行模拟调用10秒一次定时任务请求线程执行睡眠20秒后完成。下面看一下执行结果。当获取锁后第二次定时任务执行时。锁未被释放。所以失败第三次获取时所已经释放所以成功。 如果拿到分布式锁的节点宕机且这个锁正好处于锁住的状态时会出现锁死的状态为了避免这种情况的发生锁都会设置一个过期时间。这样也存在一个问题加入一个线程拿到了锁设置了30s超时在30s后这个线程还没有执行完毕锁超时释放了就会导致问题Redisson给出了自己的答案就是 watch dog 自动延期机制。 Redisson提供了一个监控锁的看门狗它的作用是在Redisson实例被关闭前不断的延长锁的有效期也就是说如果一个拿到锁的线程一直没有完成逻辑那么看门狗会帮助线程不断的延长锁超时时间锁不会因为超时而被释放。 默认情况下看门狗的续期时间是30s也可以通过修改Config.lockWatchdogTimeout来另行指定。另外Redisson 还提供了可以指定leaseTime参数的加锁方法来指定加锁的时间。超过这个时间后锁便自动解开了不会延长锁的有效期。 3.redisson源码 Redisson的源码版本基于3.16.4同时需要注意的是 watchDog 只有在未显示指定加锁时间leaseTime时才会生效。这点很重要 lockWatchdogTimeout设定的时间不要太小 比如我之前设置的是 100毫秒由于网络直接导致加锁完后watchdog去延期时这个key在redis中已经被删除了。 在调用lock方法时会最终调用到tryAcquireAsync。调用链为lock()-tryAcquire-tryAcquireAsync,详细解释如下 使用了RFuture相关内容涉及Netty异步回调模式-Future和Promise剖析去启动异步线程执行 private T RFutureLong tryAcquireAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId) {RFutureLong ttlRemainingFuture;//如果指定了加锁时间会直接去加锁if (leaseTime ! -1) {ttlRemainingFuture tryLockInnerAsync(waitTime, leaseTime, unit, threadId, RedisCommands.EVAL_LONG);} else {//没有指定加锁时间 会先进行加锁并且默认时间就是 LockWatchdogTimeout的时间//这个是异步操作 返回RFuture 类似netty中的futurettlRemainingFuture tryLockInnerAsync(waitTime, internalLockLeaseTime,TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);}//这里也是类似netty Future 的addListener在future内容执行完成后执行ttlRemainingFuture.onComplete((ttlRemaining, e) - {if (e ! null) {return;}// lock acquiredif (ttlRemaining null) {// leaseTime不为-1时不会自动延期if (leaseTime ! -1) {internalLockLeaseTime unit.toMillis(leaseTime);} else {//这里是定时执行 当前锁自动延期的动作,leaseTime为-1时才会自动延期scheduleExpirationRenewal(threadId);}}});return ttlRemainingFuture;}scheduleExpirationRenewal 中会调用renewExpiration。 这里我们可以看到是启用一个timeout定时去执行延期动作 private void renewExpiration() {ExpirationEntry ee EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ee null) {return;}Timeout task commandExecutor.getConnectionManager().newTimeout(new TimerTask() {Overridepublic void run(Timeout timeout) throws Exception {ExpirationEntry ent EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ent null) {return;}Long threadId ent.getFirstThreadId();if (threadId null) {return;}RFutureBoolean future renewExpirationAsync(threadId);future.onComplete((res, e) - {if (e ! null) {log.error(Cant update lock getRawName() expiration, e);EXPIRATION_RENEWAL_MAP.remove(getEntryName());return;}if (res) {//如果 没有报错就再次定时延期// reschedule itselfrenewExpiration();} else {cancelExpirationRenewal(null);}});}// 这里我们可以看到定时任务 是 lockWatchdogTimeout 的1/3时间去执行 renewExpirationAsync}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);ee.setTimeout(task);}protected RFutureBoolean renewExpirationAsync(long threadId) {return this.evalWriteAsync(this.getRawName(), 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(this.getRawName()), this.internalLockLeaseTime, this.getLockName(threadId));} 结论 watch dog 在当前节点存活时每10s给分布式锁的key续期 30swatch dog 机制启动且代码中没有释放锁操作时watch dog 会不断的给锁续期如果程序释放锁操作时因为异常没有被执行那么锁无法被释放所以释放锁操作一定要放到 finally {} 中要使 watchLog机制生效 lock时 不要设置 过期时间watchlog的延时时间 可以由 lockWatchdogTimeout指定默认延时时间但是不要设置太小。如100watchdog 会每 lockWatchdogTimeout/3时间去延时。watchdog 通过 类似netty的 Future功能来实现异步延时watchdog 最终还是通过 lua脚本来进行延时
http://www.dnsts.com.cn/news/110097.html

相关文章:

  • 自己做抽奖网站违法舒城县建设局官方网站
  • 外贸网站 中英广州活动策划公司排名
  • 网站设计与网页制作教程wordpress 火车头接口
  • 池州网站优化公司建设网站费用记什么科目
  • 成都市网站制作石家庄网站搭建定制
  • 怎么制作网站视频教程步骤优化网站快速排名软件
  • 做网站和做电脑软件差别大吗什么是三合一网站建设
  • 天津市做企业标准网站上海网站建设接单
  • 蒙阴做网站网站ip地址范围
  • 网站建设页面设计图片室内设计效果图app
  • 网站无法上传图片网站案例欣赏
  • 荣胜网络 宁波网站建设云南网站建
  • 手机网站域名和pc域名的区别百度网盘资源搜索入口
  • 郑州网站建设最好国际1688网站
  • 自己做资讯网站汕头制作网站
  • 网站备案 人在上海怎么把店地址申请百度地图
  • 服务专业的网站开发设计做一个大型网站需要多少钱
  • 手术室专科建设网站新网网站模板
  • 浙江昆仑建设集团网站wordpress single模板
  • 邢台做网站公司排名网站收录突然减少
  • 台州市临海建设局网站wordpress自定义面板
  • 网站建设主管招聘赣州稳稳科技有限公司
  • 请人做网站 我需要知道哪几点网站开发设计思想
  • 机顶盒做网站临时网站搭建
  • 有那些方法推广网站论文查重网站建设
  • 电子商城网站建设项目规划书山西网络公司公司
  • 西安网站搭建公司虚拟主机wordpress多站点
  • 门户网站建设情况现代网站制作
  • 建设外贸网站费用低价手机网站建设
  • 哪里做百度网站用什么程序做网站