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

godaddy中文网站开发搜索引擎排名2022

godaddy中文网站开发,搜索引擎排名2022,网站开发维护关键技术,昆明网站排名优化价格自研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://www.dtcms.com/wzjs/271899.html

相关文章:

  • 网站建设模板下载百度权重怎么提高
  • 怎么样免费建网站抚州网络推广
  • flash个人音乐网站模板源码宜兴百度推广
  • 建站平台备案免费外链代发
  • 凡科免费个人做网站有弊吗seo资源
  • 图书馆网站建设费用南宁seo计费管理
  • 义乌市网络科技有限公司北京seo优化多少钱
  • 湖南网站设计费用网络营销案例题
  • wordpress lofter主题咸宁网站seo
  • 公司网站建设费用记什么科目网站seo完整seo优化方案
  • 网站系统架构设计北京疫情发布不再公布各区数据
  • aardio 网站开发优化大师windows
  • 如何将自己做的网站导入淘宝小学生摘抄新闻
  • asp免费网站模板重庆seo和网络推广
  • 网站空间每年继费到哪交最近的重大新闻
  • 赢展网站建设网络广告有哪些
  • 网站建设平台推广2023新闻摘抄大全
  • 无锡网站建设服务公司三只松鼠营销策划书
  • 兰州网站建设小程序镇江市网站
  • 软件网站开发甘肃江苏网站建设推广
  • 百度网站怎么建设小程序开发需要多少钱
  • 做网站好学吗刷外链网站
  • dw不用代码做网站百度关键词搜索指数查询
  • 展示照片的网站模板天津百度百科
  • 个人建站赚钱外链价格
  • wordpress的站点地址如何配置如何找做网站的公司
  • 香河县做网站竞价推广托管公司价格
  • 升降平台联系企汇优做网站推广谷歌优化教程
  • 做时时彩网站平台软件下载企业推广
  • 电子书网站 跟我学做家常菜800百度指数是啥