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

珠海企业网站建站自贡企业网站

珠海企业网站建站,自贡企业网站,营销型网站建设汽车,wordpress 新建php页面基于Redis的实现方式 1、选用Redis实现分布式锁原因#xff1a; #xff08;1#xff09;Redis有很高的性能#xff1b; #xff08;2#xff09;Redis命令对此支持较好#xff0c;实现起来比较方便 2、使用命令介绍#xff1a; #xff08;1#xff09;SETNX SETNX … 基于Redis的实现方式 1、选用Redis实现分布式锁原因 1Redis有很高的性能 2Redis命令对此支持较好实现起来比较方便 2、使用命令介绍 1SETNX SETNX key val当且仅当key不存在时set一个key为val的字符串返回1若key存在则什么都不做返回0。 2expire expire key timeout为key设置一个超时时间单位为second超过这个时间锁会自动释放避免死锁。 3delete delete key删除key 在使用Redis实现分布式锁的时候主要就会使用到这三个命令。 3、实现思想 1获取锁的时候使用setnx加锁并使用expire命令为锁添加一个超时时间超过该时间则自动释放锁锁的value值为一个随机生成的UUID通过此在释放锁的时候进行判断。 2获取锁的时候还设置一个获取的超时时间若超过这个时间则放弃获取锁。 3释放锁的时候通过UUID判断是不是该锁若是该锁则执行delete进行锁释放。 4、 分布式锁的简单实现代码 /*** 分布式锁的简单实现代码* Created by liuyang on 2017/4/20.*/ public class DistributedLock {private final JedisPool jedisPool;public DistributedLock(JedisPool jedisPool) {this.jedisPool jedisPool;}/*** 加锁* param lockName 锁的key* param acquireTimeout 获取超时时间* param timeout 锁的超时时间* return 锁标识*/public String lockWithTimeout(String lockName, long acquireTimeout, long timeout) {Jedis conn null;String retIdentifier null;try {// 获取连接conn jedisPool.getResource();// 随机生成一个valueString identifier UUID.randomUUID().toString();// 锁名即key值String lockKey lock: lockName;// 超时时间上锁后超过此时间则自动释放锁int lockExpire (int) (timeout / 1000);// 获取锁的超时时间超过这个时间则放弃获取锁long end System.currentTimeMillis() acquireTimeout;while (System.currentTimeMillis() end) {if (conn.setnx(lockKey, identifier) 1) {conn.expire(lockKey, lockExpire);// 返回value值用于释放锁时间确认retIdentifier identifier;return retIdentifier;}// 返回-1代表key没有设置超时时间为key设置一个超时时间if (conn.ttl(lockKey) -1) {conn.expire(lockKey, lockExpire);}try {Thread.sleep(10);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}} catch (JedisException e) {e.printStackTrace();} finally {if (conn ! null) {conn.close();}}return retIdentifier;}/*** 释放锁* param lockName 锁的key* param identifier 释放锁的标识* return*/public boolean releaseLock(String lockName, String identifier) {Jedis conn null;String lockKey lock: lockName;boolean retFlag false;try {conn jedisPool.getResource();while (true) {// 监视lock准备开始事务conn.watch(lockKey);// 通过前面返回的value值判断是不是该锁若是该锁则删除释放锁if (identifier.equals(conn.get(lockKey))) {Transaction transaction conn.multi();transaction.del(lockKey);ListObject results transaction.exec();if (results null) {continue;}retFlag true;}conn.unwatch();break;}} catch (JedisException e) {e.printStackTrace();} finally {if (conn ! null) {conn.close();}}return retFlag;} }5、测试刚才实现的分布式锁 例子中使用50个线程模拟秒杀一个商品使用–运算符来实现商品减少从结果有序性就可以看出是否为加锁状态。 模拟秒杀服务在其中配置了jedis线程池在初始化的时候传给分布式锁供其使用。 /*** Created by liuyang on 2017/4/20.*/ public class Service {private static JedisPool pool null;private DistributedLock lock new DistributedLock(pool);int n 500;static {JedisPoolConfig config new JedisPoolConfig();// 设置最大连接数config.setMaxTotal(200);// 设置最大空闲数config.setMaxIdle(8);// 设置最大等待时间config.setMaxWaitMillis(1000 * 100);// 在borrow一个jedis实例时是否需要验证若为true则所有jedis实例均是可用的config.setTestOnBorrow(true);pool new JedisPool(config, 127.0.0.1, 6379, 3000);}public void seckill() {// 返回锁的value值供释放锁时候进行判断String identifier lock.lockWithTimeout(resource, 5000, 1000);System.out.println(Thread.currentThread().getName() 获得了锁);System.out.println(--n);lock.releaseLock(resource, identifier);} }模拟线程进行秒杀服务 public class ThreadA extends Thread {private Service service;public ThreadA(Service service) {this.service service;}Overridepublic void run() {service.seckill();} }public class Test {public static void main(String[] args) {Service service new Service();for (int i 0; i 50; i) {ThreadA threadA new ThreadA(service);threadA.start();}} }结果如下结果为有序的 若注释掉使用锁的部分 public void seckill() {// 返回锁的value值供释放锁时候进行判断//String indentifier lock.lockWithTimeout(resource, 5000, 1000);System.out.println(Thread.currentThread().getName() 获得了锁);System.out.println(--n);//lock.releaseLock(resource, indentifier); }从结果可以看出有一些是异步进行的 上述实现存在的问题 非原子性操作   加锁setnx和锁超时expire两个命令未非原子性操作当执行加锁setnx后若因网络或客户端问题锁超时expire命令未成功执行时锁将无法被释放。 解决方案   使用set命令取代setnx和expire命令。setnx本身不支持设置超时时间。在Redis 2.6.12以上版本为set指令增加了可选参数伪代码setkey, value, expire。 误删锁 设想如下情形   1JVM1使用set(001, 002, 30)成功获取锁并设置超时时间为30s   2JVM1开始数据处理处理时间已经超过了30s...   3服务器检测到(001, 002, 30)数据超时将自动执行del进行数据删除此时JVM1还在数据处理...   4此时JVM2使用set(001, 002, 30)成功获取锁并设置超时时间为30s   5JVM2开始数据处理。与此同时JVM1处理完成操作提交后根据商品id001执行了del     到此JVM1成功误删了JVM2的锁。 解决方案   del数据之前增加锁判断机制判断要删除的锁是否属于本线程。操作流程   1加锁set(id, threadId,expire)其中value为当前线程ID   2解锁执行del命令时根据id和threadId数据判断该锁是否仍属于本线程。是则删除。 并发问题   基于误删锁的前提下由于我们无法确定程序成功处理完成数据的具体时间这就为超时时间的设置提出了难题。设置时间过长、过短都将影响程序并发的效率。 解决方案JVM1需要自己判断在超时时间内是否完成数据处理如未完成应请求延长超时时间。具体操作   为获取锁的锁的线程开启一个守护线程。当29秒时或更早线程A还没执行完守护线程会执行expire指令为这把锁“续命”20秒。守护线程从第29秒开始执行每20秒执行一次。当线程A执行完任务会显式关掉守护线程。 image 另一种情况如果节点1 忽然断电由于线程A和守护线程在同一个进程守护线程也会停下。当过了超时时间后没有守护进程的“续命”锁将自动释放。 Redisson实现Redis分布式锁的底层原理 好的接下来就通过一张手绘图给大家说说Redisson这个开源框架对Redis分布式锁的实现原理。 1加锁机制 咱们来看上面那张图现在某个客户端要加锁。如果该客户端面对的是一个redis cluster集群他首先会根据hash节点选择一台机器。 这里注意仅仅只是选择一台机器这点很关键 紧接着就会发送一段lua脚本到redis上那段lua脚本如下所示 https://img2.sycdn.imooc.com/5cad94d10001b02806590338.jpg 为啥要用lua脚本呢 因为一大坨复杂的业务逻辑可以通过封装在lua脚本中发送给redis保证这段复杂业务逻辑执行的原子性。 那么这段lua脚本是什么意思呢 KEYS[1]代表的是你加锁的那个key比如说 RLock lock redisson.getLock(myLock); 这里你自己设置了加锁的那个锁key就是“myLock”。 ARGV[1]代表的就是锁key的默认生存时间默认30秒。 ARGV[2]代表的是加锁的客户端的ID类似于下面这样 8743c9c0-0795-4907-87fd-6c719a6b4586:1 给大家解释一下第一段if判断语句就是用“exists myLock”命令判断一下如果你要加锁的那个锁key不存在的话你就进行加锁。 如何加锁呢很简单用下面的命令 hset myLock 8743c9c0-0795-4907-87fd-6c719a6b4586:1 1通过这个命令设置一个hash数据结构这行命令执行后会出现一个类似下面的数据结构 https://img4.sycdn.imooc.com/5cad94e50001d8a106640162.jpg 上述就代表“8743c9c0-0795-4907-87fd-6c719a6b4586:1”这个客户端对“myLock”这个锁key完成了加锁。 接着会执行“pexpire myLock 30000”命令设置myLock这个锁key的生存时间是30秒。 好了到此为止ok加锁完成了。 2锁互斥机制 那么在这个时候如果客户端2来尝试加锁执行了同样的一段lua脚本会咋样呢 很简单第一个if判断会执行“exists myLock”发现myLock这个锁key已经存在了。 接着第二个if判断判断一下myLock锁key的hash数据结构中是否包含客户端2的ID但是明显不是的因为那里包含的是客户端1的ID。 所以客户端2会获取到pttl myLock返回的一个数字这个数字代表了myLock这个锁key的剩余生存时间。比如还剩15000毫秒的生存时间。 此时客户端2会进入一个while循环不停的尝试加锁。 3watch dog自动延期机制 客户端1加锁的锁key默认生存时间才30秒如果超过了30秒客户端1还想一直持有这把锁怎么办呢 简单只要客户端1一旦加锁成功就会启动一个watch dog看门狗他是一个后台线程会每隔10秒检查一下如果客户端1还持有锁key那么就会不断的延长锁key的生存时间。 4可重入加锁机制 那如果客户端1都已经持有了这把锁了结果可重入的加锁会怎么样呢 比如下面这种代码 https://img1.sycdn.imooc.com/5cad94f60001654e06620453.jpg 这时我们来分析一下上面那段lua脚本。 第一个if判断肯定不成立“exists myLock”会显示锁key已经存在了。 第二个if判断会成立因为myLock的hash数据结构中包含的那个ID就是客户端1的那个ID也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1” 此时就会执行可重入加锁的逻辑他会用 incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:1 1 通过这个命令对客户端1的加锁次数累加1。 此时myLock数据结构变为下面这样 大家看到了吧那个myLock的hash数据结构中的那个客户端ID就对应着加锁的次数 5释放锁机制 如果执行lock.unlock()就可以释放分布式锁此时的业务逻辑也是非常简单的。 其实说白了就是每次都对myLock数据结构中的那个加锁次数减1。 如果发现加锁次数是0了说明这个客户端已经不再持有锁了此时就会用 “del myLock”命令从redis里删除这个key。 然后呢另外的客户端2就可以尝试完成加锁了。 这就是所谓的分布式锁的开源Redisson框架的实现机制。 一般我们在生产系统中可以用Redisson框架提供的这个类库来基于redis进行分布式锁的加锁与释放锁。 6上述Redis分布式锁的缺点 其实上面那种方案最大的问题就是如果你对某个redis master实例写入了myLock这种锁key的value此时会异步复制给对应的master slave实例。 但是这个过程中一旦发生redis master宕机主备切换redis slave变为了redis master。 接着就会导致客户端2来尝试加锁的时候在新的redis master上完成了加锁而客户端1也以为自己成功加了锁。 此时就会导致多个客户端对一个分布式锁完成了加锁。 这时系统在业务语义上一定会出现问题导致各种脏数据的产生。 所以这个就是redis cluster或者是redis master-slave架构的主从异步复制导致的redis分布式锁的最大缺陷在redis master实例宕机的时候可能导致多个客户端同时完成加锁。 引用本文章只供本人学习以及学习的记录如有侵权请联系我删除 拜托面试请不要再问我Redis分布式锁的实现原理 分布式锁简单入门以及三种实现方式介绍 Redis实现分布式锁 最后编辑于2024-11-11 21:08:36 © 著作权归作者所有,转载或内容合作请联系作者 喜欢的朋友记得点赞、收藏、关注哦
文章转载自:
http://www.morning.xqkcs.cn.gov.cn.xqkcs.cn
http://www.morning.mqbzk.cn.gov.cn.mqbzk.cn
http://www.morning.qxwrd.cn.gov.cn.qxwrd.cn
http://www.morning.jjzbx.cn.gov.cn.jjzbx.cn
http://www.morning.c-ae.cn.gov.cn.c-ae.cn
http://www.morning.dtgjt.cn.gov.cn.dtgjt.cn
http://www.morning.wtdyq.cn.gov.cn.wtdyq.cn
http://www.morning.tlzbt.cn.gov.cn.tlzbt.cn
http://www.morning.hwprz.cn.gov.cn.hwprz.cn
http://www.morning.qkrzn.cn.gov.cn.qkrzn.cn
http://www.morning.sblgt.cn.gov.cn.sblgt.cn
http://www.morning.rttxx.cn.gov.cn.rttxx.cn
http://www.morning.fypgl.cn.gov.cn.fypgl.cn
http://www.morning.yszrk.cn.gov.cn.yszrk.cn
http://www.morning.tldhq.cn.gov.cn.tldhq.cn
http://www.morning.vjdofuj.cn.gov.cn.vjdofuj.cn
http://www.morning.ymhjb.cn.gov.cn.ymhjb.cn
http://www.morning.xsgxp.cn.gov.cn.xsgxp.cn
http://www.morning.nmwgd.cn.gov.cn.nmwgd.cn
http://www.morning.rylr.cn.gov.cn.rylr.cn
http://www.morning.cftkz.cn.gov.cn.cftkz.cn
http://www.morning.qnxtz.cn.gov.cn.qnxtz.cn
http://www.morning.btblm.cn.gov.cn.btblm.cn
http://www.morning.xrqkm.cn.gov.cn.xrqkm.cn
http://www.morning.wkqrp.cn.gov.cn.wkqrp.cn
http://www.morning.hylbz.cn.gov.cn.hylbz.cn
http://www.morning.horihe.com.gov.cn.horihe.com
http://www.morning.sqyjh.cn.gov.cn.sqyjh.cn
http://www.morning.qstjr.cn.gov.cn.qstjr.cn
http://www.morning.gqjzp.cn.gov.cn.gqjzp.cn
http://www.morning.gmjkn.cn.gov.cn.gmjkn.cn
http://www.morning.kfwqd.cn.gov.cn.kfwqd.cn
http://www.morning.xbptx.cn.gov.cn.xbptx.cn
http://www.morning.tsmcc.cn.gov.cn.tsmcc.cn
http://www.morning.rwpjq.cn.gov.cn.rwpjq.cn
http://www.morning.tkcct.cn.gov.cn.tkcct.cn
http://www.morning.jiuyungps.com.gov.cn.jiuyungps.com
http://www.morning.rtryr.cn.gov.cn.rtryr.cn
http://www.morning.whothehellami.com.gov.cn.whothehellami.com
http://www.morning.xfncq.cn.gov.cn.xfncq.cn
http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn
http://www.morning.sbrrf.cn.gov.cn.sbrrf.cn
http://www.morning.tdzxy.cn.gov.cn.tdzxy.cn
http://www.morning.ldynr.cn.gov.cn.ldynr.cn
http://www.morning.rfxw.cn.gov.cn.rfxw.cn
http://www.morning.qkqpy.cn.gov.cn.qkqpy.cn
http://www.morning.zlchy.cn.gov.cn.zlchy.cn
http://www.morning.mttck.cn.gov.cn.mttck.cn
http://www.morning.zsrjn.cn.gov.cn.zsrjn.cn
http://www.morning.jwxmn.cn.gov.cn.jwxmn.cn
http://www.morning.tnhmp.cn.gov.cn.tnhmp.cn
http://www.morning.lwgsk.cn.gov.cn.lwgsk.cn
http://www.morning.mzydm.cn.gov.cn.mzydm.cn
http://www.morning.flpjy.cn.gov.cn.flpjy.cn
http://www.morning.ftldl.cn.gov.cn.ftldl.cn
http://www.morning.zkpwk.cn.gov.cn.zkpwk.cn
http://www.morning.nsppc.cn.gov.cn.nsppc.cn
http://www.morning.tlfzp.cn.gov.cn.tlfzp.cn
http://www.morning.wjqbr.cn.gov.cn.wjqbr.cn
http://www.morning.qghjc.cn.gov.cn.qghjc.cn
http://www.morning.nmymn.cn.gov.cn.nmymn.cn
http://www.morning.hblkq.cn.gov.cn.hblkq.cn
http://www.morning.xdpjs.cn.gov.cn.xdpjs.cn
http://www.morning.wrysm.cn.gov.cn.wrysm.cn
http://www.morning.ljwyc.cn.gov.cn.ljwyc.cn
http://www.morning.rjnx.cn.gov.cn.rjnx.cn
http://www.morning.jrhcp.cn.gov.cn.jrhcp.cn
http://www.morning.tcxzn.cn.gov.cn.tcxzn.cn
http://www.morning.wpcfm.cn.gov.cn.wpcfm.cn
http://www.morning.zrhhb.cn.gov.cn.zrhhb.cn
http://www.morning.jrqcj.cn.gov.cn.jrqcj.cn
http://www.morning.rmdsd.cn.gov.cn.rmdsd.cn
http://www.morning.ffhlh.cn.gov.cn.ffhlh.cn
http://www.morning.fpzz1.cn.gov.cn.fpzz1.cn
http://www.morning.tcsdlbt.cn.gov.cn.tcsdlbt.cn
http://www.morning.ndynz.cn.gov.cn.ndynz.cn
http://www.morning.rfdqr.cn.gov.cn.rfdqr.cn
http://www.morning.cfjyr.cn.gov.cn.cfjyr.cn
http://www.morning.wqbhx.cn.gov.cn.wqbhx.cn
http://www.morning.nicetj.com.gov.cn.nicetj.com
http://www.tj-hxxt.cn/news/257572.html

相关文章:

  • 织梦网站logo怎么换博客编辑器 wordpress
  • 免费发布信息网站平台如何查询企业邮箱
  • 平昌县建设局网站wordpress 添加手机号
  • 湛江cms建站记事本做网站的代码
  • 怎样提高网站的打开速度微信小程序网站开发
  • 如何网站建设网页百度新闻app
  • 全国论坛网站建设网站综合营销方案设计
  • 金环建设集团网站小红书sem是什么意思
  • php源码建站 一品资源wordpress 产品多个分类
  • 全球速卖通大学新网站seo技术
  • 新乡公司网站建设怎样在国外网站上做宣传
  • 综合社区网站开发费用网站建设建站公司
  • 全球网站排行网页美工怎么做
  • 基础微网站开发可信赖天津做网站最权威的公司
  • 试玩网站源码商城网站开发项目描述
  • 做电影网站多少钱合肥市城乡建设局网站打不开
  • 做的网站没法本地上传图片wordpress建站必须选择主题
  • 微商建立网站网站添加支付宝
  • 深圳建科技有限公司网站首页个人网站模板的优缺点
  • 厦门建设工程招标中心的网站汉阴做网站
  • 郑州做网站公司 汉狮网络wordpress这么用
  • 美食网站制作模板企装网
  • 网站的基本建设投资邢台集团网站建设价格
  • 网站流量分析长沙有实力的关键词优化价格
  • 秋林 做网站wordpress数据库字典
  • 模板网站官网国内常用erp系统有哪几种
  • 医学分类手机网站模版企业怎么做好网站优化
  • 东莞网站的制作设计wordpress订阅支付
  • 昆山做网站的那家好建网站 温州
  • kuake自助建站系统官网怎样做直播网站