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

酒业网站建设怎么做网站在网上能搜到你

酒业网站建设,怎么做网站在网上能搜到你,深圳推广网络,网站建设公司581 缘起 有一次同事问Redisson存储的键是否为hash#xff1f; 我当时#xff0c;没有看Redisson的相关源码#xff0c;只知道应用#xff0c; 所以没有办法回答#xff0c;于是开始看看Redisson实现的源码#xff0c; 顺便写了一个单机Redisson测试#xff0c; 发现Redi…1 缘起 有一次同事问Redisson存储的键是否为hash 我当时没有看Redisson的相关源码只知道应用 所以没有办法回答于是开始看看Redisson实现的源码 顺便写了一个单机Redisson测试 发现Redisson有看门狗功能但是不是所有的方法都会触发 只有lock()方法才会触发看门狗其他的方法不会触发看门狗功能 如lock(long, TimeUnit)tryLock() 本文从结果触发先理论分析然后代码实践验证。 先从源码讲解Redisson相关的知识包括如何新建锁、释放锁、看门狗功能 然后代码实战验证这些功能 感兴趣的同学可以手动调试。 帮助读者轻松应对知识交流与考核。 版本信息 SpringBoot2.1.7 Redisson3.7.5 2 Redisson属性源码分析与验证 2.1 新建锁 位置org.redisson.RedissonLock#tryLockInnerAsync 新建锁和可重入源码如下图所示由源码可知 Redisson使用Lua脚本新建锁。 为什么 保证操作原子性。 因为新建数据和添加过期时间是两步操作不能保证原子性 因此使用Lua实现保证新建锁时是原子操作。 Redisson实现的锁是可重入的。同一个线程获取锁无需重新排队申请只需增加锁的持有次数。 怎么做 判断锁是的属性是否存在。 通过hexists判断锁的属性是否存在UUID:threadId如果存在值1同时更新锁过期时间 使用Lua脚本保证原子性。 Lua脚本中的参数KEYS[1]ARGV[1], ARGV[2] 分别对应哪些参数呢 KEYS[1]Collections.singletonList(getName())即锁的键名 ARGV[1]internalLockLeaseTime即锁过期时间 ARGV[2]getLockName(threadId)即锁Hash属性的键UUDI:threadId。 其中getLockName源码如下图所示由图可知UUID拼接threadId作为锁属性的键。 顺便补充一下Hash结构键名即获取该Hash的键属性键名即Hash内部数据的键。 下面看一下新建锁的调试过程如下图所示 单步调试如果操作不及时或者有其他时延会导致Redis数据过期因此选择单步调试 由图可知新建的锁键名称为redisLockKey 默认锁过期时间为30秒UUID为edb0f8cb-ec11-4b29-a107-12be152c4a5e threadId为71锁属性的键为edb0f8cb-ec11-4b29-a107-12be152c4a5e:71属性键的值为1。 新建锁之后会在Redis生成对应的数据 如下图所示由图可知Redisson新建的锁键为redisLockKey 锁属性名称为edb0f8cb-ec11-4b29-a107-12be152c4a5e:71属性值为1。 过期时间TTL已经开始倒计时了实时的值为17秒。 2.2 获取锁 Redisson获取锁有两种方式lock获取和tryLock获取。 lock()获取锁如果得不到会一直等同时lock()会开启看门狗功能在看门狗巡查期间锁不会过期 lock(long, java.util.concurrent.TimeUnit)获取锁会一直等当锁过期后即可自动获取 tryLock()获取锁得不到会一直等当锁过期后可自动获取到 tryLock(long, long, java.util.concurrent.TimeUnit)获取锁有两个时间参数可以同时指定等待锁的最大时间以及锁过期时间如果等待最大时间大于锁过期时间则锁被提前释放重新生成锁 2.2.1 lock 位置java.util.concurrent.locks.Lock#lock 无参的lock方法来自JUC接口 Redisson自身实现lock并加入看门狗功能。 无返回值。 Redisson的实现源码如下图所示这里给出路径感兴趣可自行查看。 位置org.redisson.RedissonLock#lock() 有参的lock源码如下图所示 这个lock来自Redisson的RLock添加了锁过期时间 可以自定义锁的过期时间这个获取锁的方法不会触发看门狗。 无返回值。 位置org.redisson.api.RLock#lock Redisson实现源码如下这里给出路径感兴趣可自行查看。 位置org.redisson.RedissonLock#lock(long, java.util.concurrent.TimeUnit) 2.2.2 tryLock 位置java.util.concurrent.locks.Lock#tryLock() 获取锁无法获取时等待当锁自动过期后可自动获取。 有返回值可通过返回值判断是否获得锁。 true成功获取锁 false未获取锁。 Redisson实现tryLock源码如下图所示。 位置org.redisson.RedissonLock#tryLock() 有参数的tryLock源码下图所示有源码可知 可指定最大等待锁时间、锁过期时间 如果等待锁的最大时间小于锁过期时间返回false标识未得到锁。 如果等待锁的最大时间大于锁过期时间等锁释放后可自动获取锁返回true标识得到锁。 有返回值可通过返回值判断是否获得锁。 true成功获取锁 false未获取锁。 位置org.redisson.api.RLock#tryLock 获取锁的实现源码如下图所示这里给出路径感兴趣可自行查看。 位置org.redisson.RedissonLock#tryLock(long, long, java.util.concurrent.TimeUnit) 2.3 释放锁 位置org.redisson.RedissonLock#unlockInnerAsync 释放锁源码如下图所示由图可知释放锁时会将锁属性的值-1加-1 当释放的锁存在时会将锁属性的值减1减后的值大于零重置锁的过期时间保证锁的过期时间周期 如果减1之后锁属性值为0即没有线程再持有锁则删除该锁del。 2.4 锁续期 看门狗 位置org.redisson.config.Config#lockWatchdogTimeout 看门狗的默认超时时间为30秒即锁过期时间的续期为30秒 看门狗的巡查周期为10秒即每10秒更新一次锁的过期时间设置为30秒。 两个是独立的时间系统。 30秒锁的过期时间 10秒看门狗巡查周期。 这个10秒是如何得到的30/310。 位置org.redisson.RedissonLock#scheduleExpirationRenewal 看门狗进行锁续期的源码如下图所示由源码可知 当锁存在时会延迟10秒执行更新锁过期时间过期时间为30秒 看门狗的巡查周期就是这个延迟时间10秒。 当然好奇的同学会问锁的默认过期时间怎么就是30秒 这个30秒是从哪里来的呢 过期时间internalLockLeaseTime默认值取自看门狗的超时时间30秒上文有看门狗的默认值源码。 3 实战 版本信息 SpringBoot2.1.7 Redisson3.7.5 3.1 依赖 !--Redisson-- dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.7.5/version /dependency3.2 配置 3.2.1 Redis配置 application-dev.yml spring:profiles: devredis:host: localhostport: 6379# 连接超时时间毫秒timeout: 60000database: 0lettuce:pool:# 连接池最大连接数量max-active: 8# 连接池最大阻塞等待时间-1无限制max-wait: 60000# 连接池最大空闲连接数量max-idle: 8# 连接池最小空闲连接数量min-idle: 03.2.2 绑定Redis配置 package com.hardsoft.monkeyrun.common.lock;import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration;/*** Redis连接参数.** author xindaqi* since 2021/4/2 11:41*/ Configuration ConfigurationProperties(prefixspring.redis) public class RedisConnectionParams {/*** 主机名*/private String host;/*** 主机端口*/private String port;/*** Redis连接超时时间毫秒*/private int timeout;/*** Redis数据库编号*/private int database;public void setHost(String host) {this.host host;}public String getHost() {return host;}public void setPort(String port) {this.port port;}public String getPort() {return port;}public void setTimeout(int timeout) {this.timeout timeout;}public int getTimeout() {return timeout;}public void setDatabase(int database) {this.database database;}public int getDatabase() {return database;}Overridepublic String toString() {return RedisConnectionParams{ host host \ , port port \ , timeout timeout , database database };} }3.2.3 Redisson配置 package com.hardsoft.monkeyrun.common.config;import com.hardsoft.monkeyrun.common.lock.RedisConnectionParams; import com.hardsoft.monkeyrun.common.lock.RedissonLocker; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.SingleServerConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;import static com.hardsoft.monkeyrun.common.constrant.StringConstant.COLON; import static com.hardsoft.monkeyrun.common.constrant.StringConstant.REDISSON_SCHEMA;/*** Redisson配置.** author xindaqi* since 2021/4/2 11:34*/ Configuration public class RedissonConfig {ResourceRedisConnectionParams redisConnectionParams;/*** 单机模式RedissonClient** return*/Bean(destroyMethod shutdown)public RedissonClient redissonClient() {Config config new Config();SingleServerConfig singleServerConfig config.useSingleServer();StringBuilder redisAddress new StringBuilder();redisAddress.append(REDISSON_SCHEMA).append(redisConnectionParams.getHost()).append(COLON).append(redisConnectionParams.getPort());singleServerConfig.setAddress(redisAddress.toString());return Redisson.create(config);}Beanpublic RedissonLocker redissonLocker(RedissonClient redissonClient) {return new RedissonLocker(redissonClient);}}3.2.4 Redisson获取锁封装 package com.hardsoft.monkeyrun.common.lock;import com.hardsoft.monkeyrun.common.constrant.BooleanConstant; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component;import javax.annotation.Resource; import java.util.concurrent.TimeUnit;/*** Redisson锁** author xindaqi* since 2021/3/30 19:01*/ Component public class RedissonLocker {RedissonClient redissonClient;public RedissonLocker(RedissonClient redissonClient) {this.redissonClient redissonClient;}/*** 获取锁* 如果锁不可用则当前线程处于休眠状态直到获得锁为止** param lockKey 锁键*/public void lock(String lockKey) {RLock lock redissonClient.getLock(lockKey);lock.lock();}/*** 获取锁* 如果锁不可用则当前线程处于休眠状态直到获得锁为止* 如果获取到锁后执行结束后解锁或达到超时时间后自动释放锁** param lockKey 锁键* param timeout 超时时间*/public void lock(String lockKey, int timeout) {RLock lock redissonClient.getLock(lockKey);lock.lock(timeout, TimeUnit.SECONDS);}/*** 获得锁* 如果锁不可用则当前线程处于休眠状态直到获得锁后* 执行结束后解锁或达到超时时间后会自动释放锁** param lockKey 锁键* param unit 时间单位* param timeout 超时时间*/public void lock(String lockKey, TimeUnit unit, int timeout) {RLock lock redissonClient.getLock(lockKey);lock.lock(timeout, unit);}/*** 释放锁** param lockKey 锁键*/public void unlock(String lockKey) {RLock lock redissonClient.getLock(lockKey);lock.unlock();}/*** 尝试获取锁* 获取到立即返回True* 未获取到返回False** param lockKey 锁键* return 获取锁标志位True成功获取锁False未获取锁*/public boolean tryLock(String lockKey) {RLock lock redissonClient.getLock(lockKey);return lock.tryLock();}/*** 尝试获取锁* 在等待时间内获取到锁则返回True否则返回False* 获取到锁两种执行逻辑* 1.执行之后释放锁* 2.达到释放时间leaseTime后释放锁** param lockKey 锁键* param waitTime 等待时间* param leaseTime 释放时间* param unit 时间单位* return 获取锁标志位True成功获取锁False未获取锁* throws InterruptedException*/public boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {RLock lock redissonClient.getLock(lockKey);return lock.tryLock(waitTime, leaseTime, unit);}/*** 判断锁是否被任意一个线程持有** param lockKey 锁键* return 锁持有标志位True锁被线程持有False锁没有被线程持有*/public boolean isLocked(String lockKey) {RLock lock redissonClient.getLock(lockKey);return lock.isLocked();}public void setRedissonClient(RedissonClient redissonClient) {this.redissonClient redissonClient;} }3.3 接口测试 package com.hardsoft.monkeyrun.api.facade.lock;import com.hardsoft.monkeyrun.common.constrant.BooleanConstant; import com.hardsoft.monkeyrun.common.constrant.DigitalConstant; import com.hardsoft.monkeyrun.common.enums.BizExceptionCodeEnums; import com.hardsoft.monkeyrun.common.exception.BizException; import com.hardsoft.monkeyrun.common.lock.RedissonLocker; import com.hardsoft.monkeyrun.common.response.Response;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.util.concurrent.TimeUnit;import static com.hardsoft.monkeyrun.common.constrant.StringConstant.REDIS_LOCK_KEY;/*** 锁测试** author xindaqi* since 2021-04-03 11:28:18*/ RestController RequestMapping(/v1/lock) public class LockTest {private static final Logger logger LoggerFactory.getLogger(LockTest.class);private final String STOCK_WITH_REDISSON stock_with_redisson;private final String STOCK_WITHOUT_REDISSON stock_without_redisson;ResourceRedissonLocker redissonLocker;/*** 测试Redisson锁tryLock不会激活看门狗锁过期后直接被清除* * return 响应*/GetMapping(/redisson/try-lock/test)public ResponseString testRedissonTryLock() {try {boolean lock1 redissonLocker.tryLock(REDIS_LOCK_KEY, 100, 10, TimeUnit.SECONDS);if (lock1) {logger.info(得到锁);Thread.sleep(70000);return Response.success();} else {logger.info(未得到锁);return Response.fail();}} catch(Exception ex) {logger.error(Redisson异常, ex);throw new BizException(BizExceptionCodeEnums.FAIL);} finally {logger.info(释放Redisson锁);redissonLocker.unlock(REDIS_LOCK_KEY);}}/*** 测试Redisson看门狗功能使用lock()获取锁激活看门狗功能每10秒自动续期30秒过期时间。* * return 响应*/GetMapping(/redisson/lock/test)public ResponseString testRedissonLock() {try {redissonLocker.lock(REDIS_LOCK_KEY);Thread.sleep(70000);return Response.success();} catch(Exception ex) {logger.error(Redisson异常, ex);throw new BizException(BizExceptionCodeEnums.FAIL);} finally {logger.info(释放Redisson锁);redissonLocker.unlock(REDIS_LOCK_KEY);}} }Redis结果 4 结论 1Redisson锁存储使用HashHash键为锁的键名属性的键为UUID拼接ThreadId格式UUID:ThreadID如xxx-xxx:30属性的值为同一个线程获取锁的次数Redisson的锁是可重入的同一个线程获取锁锁的数量1释放锁数量减1 2Redisson获取锁有两种方式lock获取和tryLock获取其中 2.1lock获取锁时如果第一次尝试获取获取失败会一直等待直到获取锁。Redisson的lock获取锁时会为锁配置过期时间当锁超过过期时间后会自动释放避免死锁可以重新获得锁 2.2lock()原始方法获取不自定义超时过期时间会激活看门狗。即通过lock()方法成功获取锁后逻辑执行的时间超过看门狗超时时间10秒会自动为锁续期增加10秒的过期时间使锁的过期时间保持在30秒默认的锁过期时间 2.3lock(long, TimeUnit)带参方法可以指定锁过期时间但是不会触发看门狗自动续期锁过期后自动释放锁 2.4tryLock方法返回标识位获取成功返回true获取失败返回falsetryLock尝试获取锁无法获取锁时会等待同时tryLock有最大的等待时间如果获取锁的等待时间超过最大等待时间会放弃获取锁并返回falsetryLock不会触发看门狗无法自动为锁续期 2.5tryLock可以同时指定等待锁的最大时间以及锁过期时间如果等待最大时间大于锁过期时间则锁被提前释放重新生成锁 3Redisson看门狗默认巡查周期为10秒锁续期时间过期时间30秒 4Redisson看门口生效的方法为lock()其他方法均不会触发看门狗。
http://www.hkea.cn/news/14259121/

相关文章:

  • 网站建设功能需求文档网站被挂黑链怎么删除
  • 做单页购物网站用什么好哈尔滨制作网站工作室
  • 免费建立网站的有哪里做网站的无锡
  • 网站自助建站开发制作凡科网做的网站
  • 做电影资讯网站算侵权吗网站备案 ip
  • 推广网站加盟北京网站设计引流微信hyhyk1
  • 网站正在建设中的苏州360推广 网站建设
  • 网站注册界面东莞制作公司网站
  • 网站制作员益阳学校网站建设
  • 上海做公司网站多少钱网页制作软件frontpage2000属于
  • 姑苏区住房和建设局网站重庆刚刚发布
  • 网站在百度的图标显示不正常显示宜春市城市建设网站
  • 贷款超市网站开发中山网站开发
  • 提供网站建设费用哈尔滨建设银行招聘信息网
  • 建设网站公司选哪家好营销外包团队
  • 企业网站开发技术题库那些做环保网站的好
  • 建设工程平台网站深圳软件定制
  • 滨海住房和城乡建设局网站做网站美工排版
  • soho需要建网站吗WordPress下级
  • 详细论述制作网站的步骤商城模板建站
  • 郑州网站seo推广网站建设公司郑州
  • 怎么制作属于自己的网站天猫网上商城
  • 网站含义湖北什么是网络营销
  • 云南网站建设找三好科技兰州最新消息今天又封了
  • 网站开发账务处理wordpress 安卓 管理系统
  • 响应式网站开发的国内网站设计公司
  • 网站建设公司排名前十洛阳哪里有做网站的
  • 上海网站关键词优化方法建网站程序
  • 服饰网站建设规划书廊坊seo排名
  • 网站目录结构网站建设为什么要全款