汕头网站建设公司wordpress获取当前分类文章数
news/
2025/9/23 1:50:21/
文章来源:
汕头网站建设公司,wordpress获取当前分类文章数,青岛官网排名推广,wordpress 网站建设什么是分布式锁 1.1 作用#xff1a; 保证数据的正确性#xff1a; 比如#xff1a;秒杀的时候防止商品超卖#xff0c;接口幂等性。 避免重复处理数据#xff1a; 比如#xff1a;1避免调度任务在多台机器重复执行#xff0c;2避免缓存过期所有请求都去加载数据库。 一…什么是分布式锁 1.1 作用 保证数据的正确性 比如秒杀的时候防止商品超卖接口幂等性。 避免重复处理数据 比如1避免调度任务在多台机器重复执行2避免缓存过期所有请求都去加载数据库。 一个分布式锁需要考虑的问题 1互斥阻塞。2锁需要可重入。3过期时间 4锁续期 1.2 redission的实现原理是什么 1.2.1 如何解决这四个问题呢 redission如何解决互斥 : redis内部使用key冲突解决互斥也就是相同的key只能出现一次。 使用lua脚本进行加锁和设置expire保证原子。 可重入每个线程在进行获取锁前都会去生成一个唯一id, 会判断加锁是否为自己的UUID。来进行可重入判断。 锁 过期时间 通过expire进行过期过期时间。 锁续期 看门狗机制进行锁时间的续期默认锁时间设置的是30S到10S,三分之一的时候会把锁时间重新设置为30S。 取消更新锁时长的任务场景有几种 :1正常释放锁2关闭了Redisson实例客户端在持有锁的过程中崩溃也就是服务器down机看门狗也会因为无法继续运行而停止续约这样过了租约时间后锁就会被自动释放。 1.2.2 redission使用的什么数据结构。 锁结构举例,redission使用hash结构进行加锁的。 { “lock-name”: { //线程id “threadId”: “Java-VM-thread-ID”, //UUID , 用于判断可重入当设置锁时生成UUID。 “UUID”: “unique-identifier”, //看门狗守护线程进行续约。 “lockWatchdogTimeout”: “timeout-in-seconds”, //加锁时间 “internalLockLeaseTime”: “lease-time-in-seconds” } }
源码 RFuture tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand command) { internalLockLeaseTime unit.toMillis(leaseTime);
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
//加锁成功的话创建hashset并设置过期时间if (redis.call(exists, KEYS[1]) 0) then redis.call(hset, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; //如果不存在进行判断线程是否为自己。if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(hincrby, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; return redis.call(pttl, KEYS[1]);,Collections.ObjectsingletonList(getName()), internalLockLeaseTime, getLockName(threadId));} redis在设置leaseTime的情况下看门狗是不会续命的。 当不使用leaseTime的情况下会设置为-1.
1比如我加锁时间是60S 然后业务执行了70S在60S的时候锁会释放 也就出现了重复加锁的情况 所以需要根据业务设置合理的加锁时长。
2当我没有设置leaseTime时默认为-1也就是永远不停。 为了使用同一套实现 也就是 setnx expire同时使用 那么默认会设置一个时长为30S的key。 然后进行锁续命续命来解决锁失效的问题。
代码中看门狗也就是一个定时任务会在1/3的时候进行更新任务。 Timeout task commandExecutor.getConnectionManager().newTimeout(new TimerTask() { Override public void run(Timeout timeout) throws Exception { RFutureBoolean future renewExpirationAsync(threadId);future.addListener(new FutureListenerBoolean() {Overridepublic void operationComplete(FutureBoolean future) throws Exception {expirationRenewalMap.remove(getEntryName());if (!future.isSuccess()) {log.error(Cant update lock getName() expiration, future.cause());return;}if (future.getNow()) {// reschedule itselfscheduleExpirationRenewal(threadId);}}});
}}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS); internalLockLeaseTime默认为30S。 为什么redis不设置一个永久不过期的时间而是使用续期的方式进行保证永不过呢 我的理解是redis想要复用同一套代码也就是底层全部使用这一套lua。所以使用上层定时维护key时长的方式达到key永不过期的效果。 RFuture tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand command) { internalLockLeaseTime unit.toMillis(leaseTime);
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
//加锁成功的话创建hashset并设置过期时间if (redis.call(exists, KEYS[1]) 0) then redis.call(hset, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; //如果if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(hincrby, KEYS[1], ARGV[2], 1); redis.call(pexpire, KEYS[1], ARGV[1]); return nil; end; return redis.call(pttl, KEYS[1]);,Collections.ObjectsingletonList(getName()), internalLockLeaseTime, getLockName(threadId));}
实战 场景分类 1单个锁资源资源可从前端传入。简单场景 ----使用注解加锁。 2单个锁复杂场景 使用模版进行处理。 ---- 自定义使用模版加锁。 3批量场景一般资源都是后端查出相关的进行锁定这种复杂的—自定义处理使用模版加锁。 1.2.2.1 分布式锁注解 package com.pzhu.spring.cloud.alibaba.consumer.annotation;
import com.pzhu.spring.cloud.alibaba.consumer.Enum.RedisLockEnum; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit;
/** 分布式锁注解 author jinhaiyang */ Retention(RetentionPolicy.RUNTIME)//运行时生效 Target(ElementType.METHOD)//作用在方法上 public interface RedissonLock { /** key的前缀,默认取方法全限定名除非我们在不同方法上对同一个资源做分布式锁就自己指定return key的前缀 */ String prefixKey() default “”; /** springEl 表达式return 表达式 */ String key(); /** 等待锁的时间默认-1不等待直接失败,redisson默认也是-1return 单位秒 */ int waitTime() default -1; /** 自动释放锁时长默认为-1也就是不会自动释放锁。根据业务设置自动释放锁时长避免死锁return 单位秒 */ int expireTime() default -1; /** 等待锁的时间单位默认毫秒return 单位 */ TimeUnit unit() default TimeUnit.MILLISECONDS;
} 1.2.2.2 使用说明:
含义 默认值 是否必填 prefixKey 锁前缀 方法的全命名 否 key 操作锁定key 无 是 waitTime 默认锁等待 -1 否 expireTime 释放锁时间 -1 否 unit 锁时间单位 毫秒 否 1.2.2.2.1 单个资源使用示例 1.2.2.2.1.1 使用自定义注解锁资源可以通过前端传入。只能单个资源加锁。 我用reqDto中的resumeId作为加锁的key加锁的前缀为reception-web:listLock 因为没有指定默认等待时间所以立即获取到锁获取不到会自动失败。因为没有指定expireTime默认为-1所以并不会自动释放锁。 PostMapping(“list”) RedissonLock(prefixKey “reception-web:listLock” ,key “#order.id”) public List list(RequestBody Order order ) { System.out.println(JSON.toJSONString(reqDTO)); return serviceFeign.list(); } 1.2.2.2.1.2 自己有复杂业务处理的使用以下模版。
if (Boolean.TRUE.equals(redissionUtil.tryAcquire(RedisLockEnum.ROOM_ARRANGE,GatewayHeaderUtil.getHotelCode() RedissionUtil.LOCK_ARRANGE))) { try { //加锁成功后业务处理 rowHouses(orderArrangeReq); return true; } catch (Exception e) { // 加锁异常后自定义处理 log.error(“rowHouses hotelCode为{} 排房期间出现未知异常”, GatewayHeaderUtil.getHotelCode(), e); throw e; } finally { //重要 必须在finally中解锁。 redissionUtil.release(RedisLockEnum.ROOM_ARRANGE,GatewayHeaderUtil.getHotelCode() RedissionUtil.LOCK_ARRANGE); } } else { throw new ReceptionException(ReceptionEnums.ROOM_ARRANGE_NOW, ReceptionEnums.ROOM_ARRANGE_NOW.getResultMsg()); }
1.2.2.2.2 多资源加锁-批量加锁 一般不存在这种场景 比如当我要去通过团队id查询团队下的订单id锁住这些订单。我需要在业务中进行查询这种情况比较复杂所以不建议使用注解实现。 使用模版 if (Boolean.TRUE.equals(redissionUtil.multiLockTryAcquire(roomNos,GatewayHeaderUtil.getHotelCode(), 30L))) { try { rowHouses(orderArrangeReq); return true;
} catch (Exception e) { log.error(“rowHouses hotelCode为{} 房间号列表为{} 排房期间出现未知异常”,GatewayHeaderUtil.getHotelCode(), JSON.toJSONString(roomNos), e); throw e; } finally { redissionUtil.mutiLockRelease(roomNos,GatewayHeaderUtil.getHotelCode()); } } else { //加锁失败证明存在部分房间冲突 throw new ReceptionException(ReceptionEnums.ROOM_IS_ARRANGE_NOW, ReceptionEnums.ROOM_IS_ARRANGE_NOW.getResultMsg()); } 参考文章 面试官竟然问我怎么实现分布式锁幸亏我总结了全套八股文 Redis 分布式锁的正确实现原理演化历程与 Redission 实战总结
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/911041.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!