前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【笔记8-Redis分布式锁】从0开始 独立完成企业级Java电商网站开发(服务端)

【笔记8-Redis分布式锁】从0开始 独立完成企业级Java电商网站开发(服务端)

作者头像
chenchenchen
发布2020-05-26 17:13:56
3330
发布2020-05-26 17:13:56
举报
文章被收录于专栏:chenchenchenchenchenchen

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
file

Redis分布式锁优化版流程图

file
file

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

代码语言:javascript
复制
@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
  • 权重
file
file
  • ip hash
file
file
  • url hash(第三方)
file
file
  • fail(第三方)
file
file

Nginx Tomcat搭建集群

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

Tomcat集群快速入门

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

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

参考:

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Redis分布式锁
    • Redis分布式锁命令
      • Redis分布式锁流程图
        • Redis分布式锁优化版流程图
          • Spring Schedule Redis分布式锁,构建分布式任务调度
          • Tomcat集群快速入门
            • Nginx负载均衡配置、常用策略、场景及特点
              • Nginx Tomcat搭建集群
                • Tomcat集群快速入门
                相关产品与服务
                云数据库 Redis
                腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档