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

商城网站制作方案做网赌网站

商城网站制作方案,做网赌网站,wordpress 显示备案信息,建设一个有影响力的网站#x1f525;博客主页#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞#x1f44d;收藏⭐评论✍ 本章目录 1.0 基于 Redis 实现的分布式锁存在的问题 2.0 Redisson 功能概述 3.0 Redisson 具体使用 4.0 Redisson 可重入锁原理 5.0 Redisson 锁重试原理 6.0 Redisson WatchDo… 博客主页 【小扳_-CSDN博客】 ❤感谢大家点赞收藏⭐评论✍ 本章目录 1.0 基于 Redis 实现的分布式锁存在的问题 2.0 Redisson 功能概述 3.0 Redisson 具体使用 4.0 Redisson 可重入锁原理 5.0 Redisson 锁重试原理 6.0 Redisson WatchDog 机制 6.1 Redisson 是如何解决超时释放问题的呢 7.0 Redisson MultiLock 原理 7.1 Redisson 分布式锁是如何解决主从一致性问题的呢 1.0 基于 Redis 实现的分布式锁存在的问题 首先在之前基于 setnx 实现的分布式锁存在以下问题 1不可重入同一个线程无法多次获取同一把锁。 2不可重试获取锁只尝试一次就返回 false 没有重试机制。 当然这个机制是可以自己在判断完有无获取锁之后再来根据业务的需求进行手动添加代码。比如说当业务需求是需要重复尝试获取锁。则可以在判断获取锁失败之后等待一段时间再去获取锁即可。 3超时释放锁超时释放虽然可以避免死锁但如果是业务执行耗时较长也会导致锁释放存在安全隐患。 比如说当业务阻塞时间较久锁到了超时时间则会自动释放那么其他线程就会有可能获取锁成功这就出现了多个线程获取锁成功从而导致线程安全问题。 4主从一致性如果 Redis 提供了主从集群主从同步延迟当主机宕机时如果未来得及同步到其他机器上则就会出现多线程获取锁成功情况从而导致线程安全问题。 那么 Java 实现了解决以上问题的 Redisson 分布式服务类。 2.0 Redisson 功能概述 Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网络。它不仅提供了一系列的分布式的 Java 常用对象还提供了许多分布式服务其中包含了各种分布式锁的实现。 Redisson 解决了不可重入问题、不可重试问题、超时释放问题、主从一致性问题。 比如说分布式锁的可重入锁、公平锁、联锁、红锁等等。 3.0 Redisson 具体使用 1引入依赖 dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.13.6/version/dependency 2配置 RedissonClient类 import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class RedissonConfig {Beanpublic RedissonClient client(){//配置类Config config new Config();//添加redis地址这里添加了单点的地址也可以使用config.useClusterServers()添加集群地址config.useSingleServer().setAddress(redis://8.152.162.159:6379).setPassword(****);//创建客户端return Redisson.create(config);} } 3使用 RedissonClient类 AutowiredRedissonClient redissonClient;Testvoid contextLoads() throws InterruptedException {//先获取锁对象根据业务来锁定资源RLock lock redissonClient.getLock(lock);//尝试获取锁//tryLock() 进行了重写有无参、只有两个参数、有三个参数boolean b lock.tryLock(1, TimeUnit.SECONDS);if (b){System.out.println(成功获取锁!);}else {System.out.println(获取锁失败!);}} 先注入 RedissonClient 对象根据 getLock(锁) 方法获取 RLock lock 锁对象根据业务需要对资源进行锁定。   调用 lock 对象中的 tryLock() 方法来尝试获取锁该方法进行了重写 1boolean tryLock()当获取锁失败时默认不等待就是不重试获取锁默认锁的超时时间为 30 秒。 2boolean tryLock(long time, TimeUnit unit)在 time 时间内会进行重试尝试获取锁unit 为时间单位。默认锁的超时时间为 30 秒。 3boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)在获取锁失败时在 waitTime 时间内进行重试尝试获取锁锁的超时时间为 leaseTime 秒unit 为时间单位。 最后调用 lock 对象中的方法 unlock() 来释放锁。 具体代码 AutowiredRedissonClient redissonClient;Testvoid contextLoads() throws InterruptedException {//先获取锁对象根据业务来锁定资源RLock lock redissonClient.getLock(lock);//尝试获取锁//tryLock() 进行了重写有无参、只有两个参数、有三个参数boolean b lock.tryLock(1, TimeUnit.SECONDS);if (!b){System.out.println(获取锁失败!);}try {System.out.println(获取锁成功!);} catch (Exception e) {throw new RuntimeException(e);} finally {//释放锁lock.unlock();}} 4.0 Redisson 可重入锁原理 在之前的基于 setnx 实现的分布式锁是不支持可重入锁举个例子线程一来获取锁使用 setnx 来设置当设置成功则获取锁成功了线程一在获取锁成功之后再想来获取相同的锁时则再次执行 setnx 命令那一定是不可能成功获取因为 setxn 已经存在了这就是基于 setnx 来实现分布式锁不可重入锁的核心原因。 而对于 Redisson 可以实现可重入锁这是如何实现的呢 其核心原因是基于 Redis 中的哈希结构实现的分布式锁利用 key 来锁定资源对于 field 来标识唯一成功获取锁的对象而对于 value 来累计同一个线程成功获取相同的锁的次数。 具体实现思路 1尝试获取锁 先判断缓存中是否存在 key 字段如果存在则说明锁已经被成功获取这时候需要继续判断成功获取锁的对象是否为当前线程如果根据 key field 来判断是当前线程则 value  1 且还需要重置锁的超时时间如果根据 key field 判断不是当前线程则直接返回 null。如果缓存中不存在 key 字段则说明锁还没有被其他线程获取则获取锁成功。 2释放锁 当业务完成之后在释放锁之前先判断获取锁的对象是不是当前线程如果不是当前线程则说明可能由于超时锁已经被自动释放了这时候直接返回 null如果是当前线程则进行 value - 1 最后再来判断 value 是否大于 0 当大于 0 时则不能直接释放锁需要重置锁的超时时间当 value 0 时则可以真正的释放锁。 如图 又因为使用 Java 实现不能保证原子性所以需要借助 Lua 脚本实现多条 Redis 命令来保证原则性。 尝试获取锁的 Lua 脚本 释放锁的 Lua 脚本 5.0 Redisson 锁重试原理 在之前基于 setnx 实现的分布式锁获取锁只尝试一次就返回 false 没有重试机制。 而 Redisson 是如何实现锁重试的呢 实现锁重试 追踪源代码 得到该类 首先将等待时间转换为毫秒接着获取当前时间和获取当前线程 ID 再接着第一个尝试去获取锁将参数 waitTime 最大等待时间leaseTime 锁的超时时间unit 时间单位threadId 当前线程 ID 传进去 tryAcquire 方法中。 紧接着来查看 tryAcquire 方法 再查看调用的 tryAcquireAsync 方法 当指定了 leaseTime 锁的超时时间则会调用 tryLockInnerAsync 方法当没有指定 leaseTime 锁的超时时间则会调用 getLockWatchdogTimeout 方法默认超时时间为 30 秒。 接着查看 tryLockInnerAsync 方法 可以看到这就是尝试获取是的 Lua 脚本执行多条 Redis 命令。 细心可以发现如果正常获取锁则返回 null 如果获取锁失败则返回当前锁的 TTL 锁的剩余时间。 因此最后将当前锁的 TTL 返回赋值给 Long ttl 变量。 再接着往下 当 ttl null 则说明当前线程成功获取锁因此就不需要接着往下再次尝试去获取锁了。相反当 ttl ! null 则需要接着往下走重新尝试去获取锁。 判断 time 等于当前时间减去在第一次获取锁之前的时间time 也就是最大的等待时间还剩多少。判断 time 是否小于 0 若小于 0 则已经到了最大等待时间了所以不需要再继续等下去了直接返回 false 即可。 若 time 还是大于 0 则接着往下走 调用 subscribe 方法该方法可以理解成订阅锁一旦锁被释放之后该方法就会收到通知然后再去尝试获取锁。 回顾在释放锁的时候使用 Redis 命令中的 redis.call(publish, KEYS[2], ARGV[1]) 来发布消息通知锁已经被释放一旦锁被释放那么就可以成功订阅。 因此在订阅锁的过程中并不是一直死等下去而是在 time 剩余最大等待时间之内如果可以订阅锁成功才会去尝试获取锁。如果在 time 时间内订阅锁失败则会取消订阅再返回 false 。 接着往下走当在 time 时间内订阅锁成功会更新 time 时间也就是更新最大的等待时间判断 time 小于 0 则返回 false 如果 time 还是大于 0 则到了真正尝试第二次获取锁调用 tryAcquire(waitTime, leaseTime, unit, threadId) 方法将返回值再次赋值给变量 ttl 判断 ttl null 则说明成功获取锁了直接返回 true 判断 ttl ! null 则第二次获取锁还是失败由需要更新 time 了因为在调用尝试获取锁的过程中消耗时间还是挺大的同理判断更新完之后的 time 是否大于 0如果 time 小于 0则超过了剩余最大锁的超时时间返回 false 如果判断 time 仍旧大于 0 那么先判断锁的过期时间 ttl 与 剩余时间 time 如果 ttl time 则类似订阅方法一样的思路选择等待 ttl 锁的过期时间当 ttl 过期之后就会订阅该锁如果 time  ttl 则 ttl 还没有释放就不需要等 ttl 了等到 time 结束还没有订阅到锁则 time 也就小于 0 了如果在 time 时间内获取到锁再次尝试去获取锁同样的当在 ttl 时间内成功订阅了而且 time 0 则会第三次去尝试获取锁。之后的步骤都是如此这里使用了 do whlie 循环判断循环成立为 time 0当 time 0 则会退出循环。 总结在解决可重试锁过程中并不是循环不断的调用 tryAcquire(waitTime, leaseTime, unit, threadId) 方法来获取锁这样容易造成 CPU 的浪费而是通过等待锁释放再去获取锁的方式来实现的可重试锁利用信号量Semaphore和发布/订阅PubSub模式实现等待、唤醒、获取锁失败的重试机制。 6.0 Redisson WatchDog 机制 在之前基于 setnx 实现的分布式锁锁超时释放虽然可以避免死锁但是如果是业务执行耗时较长也会导致锁释放存在安全隐患。 6.1 Redisson 是如何解决超时释放问题的呢 解决超时释放的核心是当 leaseTime -1 时为了保证当前业务执行完毕才能释放锁而不是业务还没有执行完毕锁就被自动释放了。 追踪源代码 当 leaseTime -1 时默认锁的最大超时时间为 30 秒会执行以下代码。 接着点进去 WatchDog 会在锁的过期时间到期之前定期向 Redis 发送续约请求更新锁的过期时间。这通常是通过设置一个较短的过期时间和一个续约间隔来实现的。 如果持有锁的线程正常释放锁WatchDog 会停止续约操作。如果持有锁的线程崩溃或失去响应WatchDog 会在锁的过期时间到达后自动释放锁。 简单概述一下 WatchDog 机制在获取锁成功之后就会调用 scheduleExpirationRenewal(threadId) 方法开启自动续约具体是由在 map 中添加业务名称和任务定时器这个定时器会在一定时间内执行比如说 10 秒就会自动开启任务而该定时器中的任务就是不断的重置锁的最大超时时间使用递归不断的调用重置锁的时间这就保证了锁是永久被当前线程持有。  这样就可以保证执行业务之后才会释放锁。释放锁之后会取消定时任务。 7.0 Redisson MultiLock 原理 7.1 Redisson 分布式锁是如何解决主从一致性问题的呢 先搞清楚什么是主从一致性问题在集群的 Redis 中会区分出主力机和一般机器在写 Redis 命令会放到主力机中运行而主力机和一般机器需要保证数据都是一样的也就是主从同步数据在主力机中执行写命令时突然发生宕机未来得及将数据同步到其他一般机器中而且当主力机宕机之后会选出一台一般机器充当主力机这时候的主力机没有同步之前的数据那么其他线程再来写命名的时候就会出现问题了这出现了主从不一致性。 那么 Redisson 是如何来解决该问题呢 在多主架构中每台主机都可以接收写请求这样即使某一台主机宕机其他主机仍然可以继续处理写请求。 当某一台主机宕机后如果在它恢复之前有新的写操作发生可能会导致数据不一致。通过比较不同主机的数据状态可以很容易地发现这些不一致的问题。 当宕机的主机恢复后可以通过与其他主机的数据进行比较找出差异并进行数据同步确保所有主机的数据一致。 简单来说设置多台主力机每一次写命令都是一式多份当某一台主力机出现宕机了主从未来得及同步时再写命令同样一式多份这样充当主力机出现了跟其他主力机不同的结果时就很容易的发现问题了。 通过设置多台主力机并进行写操作的多份复制可以有效提高系统的可靠性并在出现问题时快速发现和解决数据不一致的问题。 具体使用
http://www.w-s-a.com/news/432950/

相关文章:

  • 大型做网站的公司有哪些wordpress注册链接无效
  • 推荐门户网站建设公司网站开发移动端
  • 公司网站的栏目设置成都十大监理公司排名
  • 安溪住房和城乡建设网站关岭县建设局网站
  • 网站域名注销备案徐州房产网
  • 筑聘网windows优化大师自动安装
  • 龙华高端网站设计门户网站建设方案公司
  • 网站开发作用网站建设哪家专业
  • 网站设计报告总结南宁商城网站推广公司
  • 淘宝做店招的网站免费网站建设自助建站
  • 重庆工信部网站绵阳公司网站建设
  • 购物网站开发流程制作企业网页
  • 定州哪里可以做网站建设项目环境影响登记表备案系统网站
  • 网站建设费属于广告费小猪网站怎么做的
  • 国内优秀设计网站站长哈尔滨微网站建设
  • 如何建设一个优秀的电商网站沐风seo
  • 从零开始学网站建设知乎安防网站下载
  • 打开网站弹出qq应用软件有哪些
  • 温州网站建设seo网站 如何做 中英文切换
  • 聊城做网站的公司资讯信阳 网站建设
  • 天津市工程建设交易网站查汗国珠海 网页设计
  • 龙果学院大型网站稳定性建设汾阳做网站
  • 湖北 个人网站备案时间域名查询备案查询
  • 网站推广方式校园网站怎么建
  • 长沙seo网站排名怎么在百度发帖
  • 织梦贷款网站模板做印章网站
  • 彭州做网站上海百度网络推广
  • 广州网站搭建快速提升网站排名荧光字网站
  • 15年做那些网站能致富做seo是什么意思
  • 各电商网站的特点网站制作2007