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

做网站用软件山西路桥建设集团网站

做网站用软件,山西路桥建设集团网站,wordpress手机认证登录,上海网站建设哪个平台好自研redis分布式锁存在的问题以及面试切入点 lock加锁关键逻辑 unlock解锁的关键逻辑 使用Redis的分布式锁 之前手写的redis分布式锁有什么缺点?? Redis之父的RedLock算法 Redis也提供了Redlock算法,用来实现基于多个实例的分布式锁。…

自研redis分布式锁存在的问题以及面试切入点
在这里插入图片描述
lock加锁关键逻辑
在这里插入图片描述
在这里插入图片描述
unlock解锁的关键逻辑
在这里插入图片描述
使用Redis的分布式锁
在这里插入图片描述
之前手写的redis分布式锁有什么缺点??
在这里插入图片描述
在这里插入图片描述
Redis之父的RedLock算法
Redis也提供了Redlock算法,用来实现基于多个实例的分布式锁。
锁变量由多个实例维护,即使有实例发生了故障,锁变量仍然是存在的,客户端还是可以完成锁操作。
Redlock算法是实现高可靠分布式锁的一种有效解决方案,可以在实际开发中使用
官网
Redis分布式锁
在这里插入图片描述

在这里插入图片描述
RedLock的设计理念
该方案也是基于(set 加锁、Lua 脚本解锁)进行改良的,所以redis之父antirez 只描述了差异的地方,大致方案如下。

假设我们有N个Redis主节点,例如 N = 5这些节点是完全独立的,我们不使用复制或任何其他隐式协调系统,

为了取到锁客户端执行以下操作:
在这里插入图片描述
该方案为了解决数据不一致的问题,直接舍弃了异步复制只使用 master 节点,同时由于舍弃了 slave,为了保证可用性,引入了 N 个节点,官方建议是 5。
本次教学演示用3台实例来做说明。客户端只有在满足下面的这两个条件时,才能认为是加锁成功。

条件1:客户端从超过半数(大于等于N/2+1)的Redis实例上成功获取到了锁;
条件2:客户端获取锁的总耗时没有超过锁的有效时间。

解决方案与容错公式
在这里插入图片描述

RedLock的落地实现Redisson

github地址

https://github.com/redisson/redisson
https://redisson.pro/docs/configuration/#cluster-mode

在这里插入图片描述
pom文件

 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.19.1</version></dependency>

RedissonConfig配置类

package com.atguigu.redislock.config;import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig
{@Beanpublic RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(lettuceConnectionFactory);//设置key序列化方式stringredisTemplate.setKeySerializer(new StringRedisSerializer());//设置value的序列化方式jsonredisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}@Beanpublic Redisson redisson(){Config config = new Config();config.useSingleServer().setAddress("redis://172.18.8.229:6379").setDatabase(0).setPassword("root");return (Redisson) Redisson.create(config);}
}

业务方法的改造

  @Autowiredprivate Redisson redisson;//V9版本public String saleV9(){String retMessage="";RLock redissonLock = redisson.getLock("redisLock");redissonLock.lock();try {//查询库存信息String result = stringRedisTemplate.opsForValue().get("inventory001");//判断库存是否足够Integer inventory =result==null?0: Integer.valueOf(result);//扣减库存if(inventory>0){stringRedisTemplate.opsForValue().set("inventory001",String.valueOf(--inventory));retMessage="成功卖出一个商品,库存剩余:"+inventory;System.out.println(retMessage+"\t"+"服务端口号"+port);try {TimeUnit.SECONDS.sleep(120);} catch (InterruptedException e) {throw new RuntimeException(e);}}else{retMessage="商品卖完了";}}finally {redissonLock.unlock();}return retMessage+"\t"+"服务端口号"+port;}

Jemeter压测
在这里插入图片描述
在这里插入图片描述
这样直接删除锁是有bug的
在这里插入图片描述
解决方案

if(redissonLock.isLocked() && redissonLock.isHeldByCurrentThread())
{
redissonLock.unlock();
} }

 @Autowiredprivate Redisson redisson;//V9版本public String saleV9(){String retMessage="";RLock redissonLock = redisson.getLock("redisLock");redissonLock.lock();try {//查询库存信息String result = stringRedisTemplate.opsForValue().get("inventory001");//判断库存是否足够Integer inventory =result==null?0: Integer.valueOf(result);//扣减库存if(inventory>0){stringRedisTemplate.opsForValue().set("inventory001",String.valueOf(--inventory));retMessage="成功卖出一个商品,库存剩余:"+inventory;System.out.println(retMessage+"\t"+"服务端口号"+port);}else{retMessage="商品卖完了";}}finally {if(redissonLock.isLocked() && redissonLock.isHeldByCurrentThread()){redissonLock.unlock();}        }return retMessage+"\t"+"服务端口号"+port;}

Redisson源码解析

  • 加锁
  • 可重入
  • 续命
  • 解锁
  • 分析步骤
    Redis分布式锁过期了,但是业务逻辑还没处理完怎么办?(还记得之前说过的缓存续命么)
    守护线程续命
    在这里插入图片描述
    在获取锁成功后,给锁加一个watch dog,watchdog会启动一个定时任务,在锁没有被释放且快要过期的时候会续期。
    在这里插入图片描述

在这里插入图片描述
源码分析
在这里插入图片描述
在这里插入图片描述
通过redissson新建出来的锁key,默认是30s

加锁的核心代码
在这里插入图片描述
在这里插入图片描述
Lua脚本加锁
在这里插入图片描述
在这里插入图片描述

  • 通过 exists 判断,如果锁不存在,则设置值和过期时间,加锁成功。
  • 通过 hexists 判断,如果锁已存在,并且锁的是当前线程,则证明是重入锁,加锁成功。
  • 如果锁已存在,但锁的不是当前线程,则证明有其他线程持有锁。返回当前锁的过期时间(代表了锁 key 的剩余生存时间),加锁失败。
    看门狗的锁续期
    在这里插入图片描述
    在这里插入图片描述
    客户端A加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端A还持有锁key,那么就会不断的延长锁key的生存时间,默认每次续命又从30秒新开始
    在这里插入图片描述
    在这里插入图片描述
    Lua脚本执行看门狗的锁续期
    在这里插入图片描述
    在这里插入图片描述
    解锁方法
    在这里插入图片描述
    在这里插入图片描述
    多机案例
    理论参考
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    实战演示:
    docker启动三个redis实例
    在这里插入图片描述
server.port=9090
spring.application.name=redlockspring.swagger2.enabled=truespring.redis.database=0
spring.redis.password=
spring.redis.timeout=3000
spring.redis.mode=singlespring.redis.pool.conn-timeout=3000
spring.redis.pool.so-timeout=3000
spring.redis.pool.size=10spring.redis.single.address1=172.18.8.229:6382
spring.redis.single.address2=172.18.8.229:6383
spring.redis.single.address3=172.18.8.229:6384

redis三个实例对应的配置类

package com.atguigu.redis.redlock.config;import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class CacheConfiguration {@AutowiredRedisProperties redisProperties;@BeanRedissonClient redissonClient1() {Config config = new Config();String node = redisProperties.getSingle().getAddress1();node = node.startsWith("redis://") ? node : "redis://" + node;SingleServerConfig serverConfig = config.useSingleServer().setAddress(node).setTimeout(redisProperties.getPool().getConnTimeout()).setConnectionPoolSize(redisProperties.getPool().getSize()).setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());if (StringUtils.isNotBlank(redisProperties.getPassword())) {serverConfig.setPassword(redisProperties.getPassword());}return Redisson.create(config);}@BeanRedissonClient redissonClient2() {Config config = new Config();String node = redisProperties.getSingle().getAddress2();node = node.startsWith("redis://") ? node : "redis://" + node;SingleServerConfig serverConfig = config.useSingleServer().setAddress(node).setTimeout(redisProperties.getPool().getConnTimeout()).setConnectionPoolSize(redisProperties.getPool().getSize()).setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());if (StringUtils.isNotBlank(redisProperties.getPassword())) {serverConfig.setPassword(redisProperties.getPassword());}return Redisson.create(config);}@BeanRedissonClient redissonClient3() {Config config = new Config();String node = redisProperties.getSingle().getAddress3();node = node.startsWith("redis://") ? node : "redis://" + node;SingleServerConfig serverConfig = config.useSingleServer().setAddress(node).setTimeout(redisProperties.getPool().getConnTimeout()).setConnectionPoolSize(redisProperties.getPool().getSize()).setConnectionMinimumIdleSize(redisProperties.getPool().getMinIdle());if (StringUtils.isNotBlank(redisProperties.getPassword())) {serverConfig.setPassword(redisProperties.getPassword());}return Redisson.create(config);}
}

controller的演示方法

@RestController
@Slf4j
public class RedLockController
{public static final String CACHE_KEY_REDLOCK = "ATGUIGU_REDLOCK";@Autowired RedissonClient redissonClient1;@Autowired RedissonClient redissonClient2;@Autowired RedissonClient redissonClient3;@GetMapping(value = "/multilock")public String getMultiLock(){String taskThreadID = Thread.currentThread().getId()+"";RLock lock1 = redissonClient1.getLock(CACHE_KEY_REDLOCK);RLock lock2 = redissonClient2.getLock(CACHE_KEY_REDLOCK);RLock lock3 = redissonClient3.getLock(CACHE_KEY_REDLOCK);RedissonMultiLock redLock = new RedissonMultiLock(lock1, lock2, lock3);redLock.lock();try{log.info("come in biz multilock:{}",taskThreadID);try { TimeUnit.SECONDS.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); }log.info("task is over multilock:{}",taskThreadID);}catch (Exception e){e.printStackTrace();log.error("multilock exception:{}",e.getCause()+"\t"+e.getMessage());}finally {redLock.unlock();log.info("释放分布式锁成功key:{}",CACHE_KEY_REDLOCK);}return "multilock task is over: "+taskThreadID;}
}

锁续期成功
在这里插入图片描述
宕机后仍然成功
在这里插入图片描述


文章转载自:

http://Wc3yW1zY.nxbzz.cn
http://uzRjriBe.nxbzz.cn
http://sELzGSKF.nxbzz.cn
http://foNMAfIx.nxbzz.cn
http://TsNS04Uc.nxbzz.cn
http://OFMBqvQM.nxbzz.cn
http://dM6bCdKk.nxbzz.cn
http://EHFo5qhi.nxbzz.cn
http://1PC6z3Ku.nxbzz.cn
http://stn0uqKw.nxbzz.cn
http://Qr64ks0K.nxbzz.cn
http://8Euw9nFK.nxbzz.cn
http://g8oggHsA.nxbzz.cn
http://EADC7Rsn.nxbzz.cn
http://qhxA7wd0.nxbzz.cn
http://dNW3FkPP.nxbzz.cn
http://LEsZDwGS.nxbzz.cn
http://hm1NDWtG.nxbzz.cn
http://LaVp7yKq.nxbzz.cn
http://I7MofUZy.nxbzz.cn
http://msB60M9t.nxbzz.cn
http://qqw4f4d1.nxbzz.cn
http://ohQMA4O6.nxbzz.cn
http://a2yVYeTr.nxbzz.cn
http://fLVcj9Ov.nxbzz.cn
http://sx4x1UhJ.nxbzz.cn
http://ZbzCEV6b.nxbzz.cn
http://hUkFuP4K.nxbzz.cn
http://xlmPTlgX.nxbzz.cn
http://i1TpU7kK.nxbzz.cn
http://www.dtcms.com/wzjs/762747.html

相关文章:

  • 青岛网站定做网站建设应该注意的问题
  • 网站开发服务费计入哪项费用网页制作与开发教程
  • 网站头部设计html网页模板大全
  • 做网站什么类型好深圳网站开发哪家服务专业
  • 网站备案号规则网站免费正能量软件直播
  • 什么是网站开发时间进度表叙述网站建设的流程
  • 湖北响应式网站建设费用微网站制作价格
  • 优惠券网站怎样做做网站如何快速推广一款产品
  • 招考网站开发wordpress图文模板下载
  • 网站建设广告素材徽章设计制作网站
  • 做网站需要多大的内存专业定制网咖装修效果图
  • 便宜网站建设免费软文推广平台
  • 一家专门做灯的网站网络营销与直播电商专业
  • 企业网站博客上如何营销站长统计
  • 2网站建设公司东莞营销网站建设
  • 平湖新埭哪里有做网站的论客企业邮箱官网
  • 教育教研网站建设的意义现在流行做网站吗
  • 深圳市做网站知名公司wordpress七牛云缩略图
  • 做网站用什么软件网站建设培训一般多少钱
  • 远近互联网站建设公司logo墙设计图片
  • 做自己照片视频网站成品网站包含后台么
  • 做建材外贸哪个网站比较好通过网站开发工具怎么改自动跳网站
  • 做图片网站天津开发区网站设计公司
  • 网页作业班级网站怎么做wordpress顶部修改
  • 财务公司管理系统太原百度seo
  • asp网站发邮件做网站的工作叫什么
  • 赣州城乡建设局网站企业文化墙素材图片
  • 购物商城网站开发目的文档南京做中英文网站设计
  • 保定网站建设苗木wordpress配置网站
  • oa报表网站开发成都市网站建设