【笔记8-Redis分布式锁】从0开始 独立完成企业级…

2020-02-11 16:05:45来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

Redis分布式锁

Redis分布式锁命令

  • setnx当且仅当 key 不存在。若给定的 key 已经存在,则?setnx不做任何动作。setnx?是『set if not exists』(如果不存在,则 set)的简写,setnx?具有原子性。?

  • getset先 get 旧值,后set 新值,并返回 key 的旧值(old value),具有原子性。当 key 存在但不是字符串类型时,返回一个错误;当key 不存在的时候,返回nil ,在Java里就是 null。?

  • expire?设置 key 的有效期?

  • del?删除 key

Redis分布式锁流程图

file

Redis分布式锁优化版流程图

file

Spring Schedule + Redis分布式锁,构建分布式任务调度

@Component

@Slf4j

public class CloseOrderTask {

private static final Loggerlog = LoggerFactory.getLogger(CloseOrderTask.class);

? ? @Autowired

? ? private IOrderServiceiOrderService;

? ? @PreDestroy  // 关闭Tomcat之前执行删除锁,避免死锁

? ? public void delLock(){

RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? }

// @Scheduled(cron = "0 */1 * * * ?")//每一分钟(每个一分钟的整数倍)

? ? public void closeOrderTaskV1(){

int hour=Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2"));

? ? ? ? log.info("关闭订单定时任务启动");

? ? ? ? iOrderService.closeorder(hour);

? ? ? ? log.info("关闭订单定时任务结束");

? ? }

//? @Scheduled(cron = "0 */1 * * * ?")//每一分钟(每个一分钟的整数倍)

? ? public void closeOrderTaskV2(){

log.info("关闭订单定时任务启动");

? ? ? ? // 锁超时时间

? ? ? ? long lockTimeout=Long.parseLong(PropertiesUtil.getProperty("lock.timeout","5000"));

? ? ? ? // 不存在则设置
                
? ? ? ? Long setnxResult= RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout));

? ? ? ? if(setnxResult!=null&&setnxResult.intValue()==1){

? ? ? ?     //如果返回值是1,代表设置成功,获取锁

? ? ? ? ? ? closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? }else{

? ? ? ? ? ? log.info("没有获得分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? }

? ? ? ? log.info("关闭订单定时任务结束");

? ? }

@Scheduled(cron ="0 */1 * * * ?")//每一分钟(每个一分钟的整数倍)

? ? public void closeOrderTaskV3(){

? ? ? ? log.info("关闭订单定时任务启动");

? ? ? ? //锁超时时间

? ? ? ? long lockTimeout=Long.parseLong(PropertiesUtil.getProperty("lock.timeout","5000"));

? ? ? ? Long setnxResult= RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout));

? ? ? ? if(setnxResult!=null&&setnxResult.intValue()==1){

? ? ? ?//如果返回值是1,代表设置成功,获取锁

? ? ? ? ? ? closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? }else{

 ? ?  ? ?  //未获取到锁,继续判断,判断时间戳,看是否可以重置并获取到锁

? ? ? ? ? ? String lockValueStr=RedisShardedPoolUtil.get(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? ? ? if(lockValueStr!=null&&System.currentTimeMillis()>Long.parseLong(lockValueStr)){

String getSetResult=RedisShardedPoolUtil.getSet(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout));

? ? ? ? ? ? ? ? //再次用当前时间戳getset

 ? ?  ? ?  ? ? //返回给定的key的旧值,-》旧值判断,是否可以获取锁

 ? ?  ? ?  ? ? //当key没有旧值时,即key不存在时,返回nil->获取锁

 ? ?  ? ?  ? ? //这里我们set了一个新的value值,获取旧的值

? ? ? ? ? ? ? ? if(getSetResult==null||(getSetResult!=null&& StringUtils.equals(lockValueStr,getSetResult))){

 ? ?  ? ?  ? ?  ? ? //真正获取到锁

? ? ? ? ? ? ? ? ? ? closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? ? ? ? ? }else{

 ? ?  ? ?  ? ?  ? ? log.info("没有获取到分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? ? ? ? ? }

 ? ? }else{

 ? ?  ? ?  ? ? log.info("没有获取到分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? ? ? }

}

 ? ? log.info("关闭订单定时任务结束");

? ? }

private void closeOrder(String lockName){

 ? ? RedisShardedPoolUtil.expire(lockName,50);//有效期5秒,防止死锁

? ? ? ? log.info("获取{} ,ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());

? ? ? ? int hour=Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2"));

? ? ? //? iOrderService.closeorder(hour);

? ? ? ? RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

? ? ? ? log.info("释放{} ,ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());

? ? ? ? log.info("============================");

? ? }

}

Tomcat集群快速入门

Nginx负载均衡配置、常用策略、场景及特点

  • 轮询(默认)

file

  • 权重

file

  • ip hash

file

  • url hash(第三方)

file

  • fail(第三方)

file

Nginx+Tomcat搭建集群

https://blog.csdn.net/Leon_Jinhai_Sun/article/details/97640796

Tomcat集群快速入门

https://blog.csdn.net/Leon_Jinhai_Sun/article/details/97624274

https://blog.csdn.net/Leon_Jinhai_Sun/article/details/97631761

参考:

https://www.jianshu.com/p/ca88c1f86069

https://blog.csdn.net/qq_20057315/article/details/81624821


原文链接:https://www.cnblogs.com/chen-chen-chen/p/12295290.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:【笔记7-部署发布】从0开始 独立完成企业级Java电商网站开发(服

下一篇:SpringCloud 基础