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

个人网站 做啥好镇江智能网站建设哪家好

个人网站 做啥好,镇江智能网站建设哪家好,安卓版下载app,网站开发工程师绩效考核表分布式锁 Redis分布式锁最简单的实现 想要实现分布式锁#xff0c;必须要求 Redis 有「互斥」的能力#xff0c;我们可以使用 SETNX 命令#xff0c;这个命令表示SET if Not Exists#xff0c;即如果 key 不存在#xff0c;才会设置它的值#xff0c;否则什么也不做。 …分布式锁 Redis分布式锁最简单的实现 想要实现分布式锁必须要求 Redis 有「互斥」的能力我们可以使用 SETNX 命令这个命令表示SET if Not Exists即如果 key 不存在才会设置它的值否则什么也不做。 两个客户端进程可以执行这个命令达到互斥就可以实现一个分布式锁。 客户端 1 申请加锁加锁成功 客户端 2 申请加锁因为它后到达加锁失败 此时加锁成功的客户端就可以去操作「共享资源」例如修改 MySQL 的某一行数据或者调用一个 API 请求。 操作完成后还要及时释放锁给后来者让出操作共享资源的机会。如何释放锁呢 也很简单直接使用 DEL 命令删除这个 key 即可这个逻辑非常简单。 但是它存在一个很大的问题当客户端 1 拿到锁后如果发生下面的场景就会造成「死锁」 1、程序处理业务逻辑异常没及时释放锁 2、进程挂了没机会释放锁 这时这个客户端就会一直占用这个锁而其它客户端就「永远」拿不到这把锁了。怎么解决这个问题呢 如何避免死锁 我们很容易想到的方案是在申请锁时给这把锁设置一个「租期」。 在 Redis 中实现时就是给这个 key 设置一个「过期时间」。这里我们假设操作共享资源的时间不会超过 10s那么在加锁时给这个 key 设置 10s 过期即可 SETNX lock 1 // 加锁 EXPIRE lock 10 // 10s后自动过期这样一来无论客户端是否异常这个锁都可以在 10s 后被「自动释放」其它客户端依旧可以拿到锁。 但现在还是有问题 现在的操作加锁、设置过期是 2 条命令有没有可能只执行了第一条第二条却「来不及」执行的情况发生呢例如 SETNX 执行成功执行EXPIRE 时由于网络问题执行失败SETNX 执行成功Redis 异常宕机EXPIRE 没有机会执行SETNX 执行成功客户端异常崩溃EXPIRE也没有机会执行 总之这两条命令不能保证是原子操作一起成功就有潜在的风险导致过期时间设置失败依旧发生「死锁」问题。 在 Redis 2.6.12 之后Redis 扩展了 SET 命令的参数用这一条命令就可以了 SET lock 1 EX 10 NX锁被别人释放怎么办 上面的命令执行时每个客户端在释放锁时都是「无脑」操作并没有检查这把锁是否还「归自己持有」所以就会发生释放别人锁的风险这样的解锁流程很不「严谨」如何解决这个问题呢 解决办法是客户端在加锁时设置一个只有自己知道的「唯一标识」进去。 例如可以是自己的线程 ID也可以是一个 UUID随机且唯一这里我们以UUID 举例 SET lock $uuid EX 20 NX之后在释放锁时要先判断这把锁是否还归自己持有伪代码可以这么写 if redis.get(lock) $uuid:redis.del(lock)这里释放锁使用的是 GET DEL 两条命令这时又会遇到我们前面讲的原子性问题了。这里可以使用lua脚本来解决。 安全释放锁的 Lua 脚本如下 if redis.call(GET,KEYS[1]) ARGV[1] thenreturn redis.call(DEL,KEYS[1]) elsereturn 0 end好了这样一路优化整个的加锁、解锁的流程就更「严谨」了。 这里我们先小结一下基于 Redis 实现的分布式锁一个严谨的的流程如下 1、加锁 SET lock_key $unique_id EX $expire_time NX2、操作共享资源 3、释放锁Lua 脚本先 GET 判断锁是否归属自己再DEL 释放锁 Java代码实现分布式锁 package com.msb.redis.lock;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.params.SetParams;import java.util.Arrays; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock;/*** 分布式锁的实现*/ Component public class RedisDistLock implements Lock {private final static int LOCK_TIME 5*1000;private final static String RS_DISTLOCK_NS tdln:;/*if redis.call(get,KEYS[1])ARGV[1] thenreturn redis.call(del, KEYS[1])else return 0 end*/private final static String RELEASE_LOCK_LUA if redis.call(get,KEYS[1])ARGV[1] then\n return redis.call(del, KEYS[1])\n else return 0 end;/*保存每个线程的独有的ID值*/private ThreadLocalString lockerId new ThreadLocal();/*解决锁的重入*/private Thread ownerThread;private String lockName lock;Autowiredprivate JedisPool jedisPool;public String getLockName() {return lockName;}public void setLockName(String lockName) {this.lockName lockName;}public Thread getOwnerThread() {return ownerThread;}public void setOwnerThread(Thread ownerThread) {this.ownerThread ownerThread;}Overridepublic void lock() {while(!tryLock()){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}Overridepublic void lockInterruptibly() throws InterruptedException {throw new UnsupportedOperationException(不支持可中断获取锁);}Overridepublic boolean tryLock() {Thread t Thread.currentThread();if(ownerThreadt){/*说明本线程持有锁*/return true;}else if(ownerThread!null){/*本进程里有其他线程持有分布式锁*/return false;}Jedis jedis null;try {String id UUID.randomUUID().toString();SetParams params new SetParams();params.px(LOCK_TIME);params.nx();synchronized (this){/*线程们本地抢锁*/if((ownerThreadnull)OK.equals(jedis.set(RS_DISTLOCK_NSlockName,id,params))){lockerId.set(id);setOwnerThread(t);return true;}else{return false;}}} catch (Exception e) {throw new RuntimeException(分布式锁尝试加锁失败);} finally {jedis.close();}}Overridepublic boolean tryLock(long time, TimeUnit unit) throws InterruptedException {throw new UnsupportedOperationException(不支持等待尝试获取锁);}Overridepublic void unlock() {if(ownerThread!Thread.currentThread()) {throw new RuntimeException(试图释放无所有权的锁);}Jedis jedis null;try {jedis jedisPool.getResource();Long result (Long)jedis.eval(RELEASE_LOCK_LUA,Arrays.asList(RS_DISTLOCK_NSlockName),Arrays.asList(lockerId.get()));if(result.longValue()!0L){System.out.println(Redis上的锁已释放);}else{System.out.println(Redis上的锁释放失败);}} catch (Exception e) {throw new RuntimeException(释放锁失败,e);} finally {if(jedis!null) jedis.close();lockerId.remove();setOwnerThread(null);System.out.println(本地锁所有权已释放);}}Overridepublic Condition newCondition() {throw new UnsupportedOperationException(不支持等待通知操作);}}
http://www.w-s-a.com/news/547426/

相关文章:

  • 生态城门户网站 建设动态it外包收费
  • 网站项目评价老渔哥网站建设公司
  • 哈尔滨寸金网站建设价格178软文网
  • 一个网站建设的成本网站开发过程及要点
  • 监控视频做直播网站中国建筑人才网下载
  • 网站建设公司华网天下买送活动集团网站设计案例
  • 哪些网站比较容易做哪个网站做中高端衣服
  • 做php网站教程wordpress去水印
  • 深圳微网站建设公司哪家好潍坊专业做网站的公司
  • 网站的弹窗广告怎么做软件开发包括
  • 网站开发人员保密做最优秀的自己演讲视频网站
  • 一般做网站要多少钱怎样选择高性价比的建站公司
  • 免费私人网站建设软件高端网站设计平台高端网站设计企业
  • 响应式网站建设的应用场景怎么申请电商平台
  • 怎么做垂直自营网站游戏咨询网站建设目标是什么
  • 建设网站需要给钱吗建立网站三大基础
  • 金融公司网站 htmlwordpress 防火墙
  • 重庆智能建站模板网站投票系统 js
  • 网站维护的内容和步骤网站做什么内容
  • 万网虚拟主机建网站wordpress协调世界时
  • 微网站建设方式应用大全网站
  • 网站速度测速织梦模板下载
  • 环保网站建设公司排名汉阴网站建设
  • 自己做网站的二维码wordpress用户权限在哪改
  • 网站使用说明书网站建设公司的介绍
  • 推广型网站免费建设网站防盗链设置
  • 建设银行网站查开户行网站反链暴增怎么回事
  • centos7做网站软件实施工程师工资一般多少
  • 专业房产网站建设深圳建设交易集团
  • 政务网站建设标准项目经理接到网站开发怎么开展