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分布式锁流程图
Redis分布式锁优化版流程图
Spring Schedule Redis分布式锁,构建分布式任务调度
@Component@Slf4jpublic class CloseOrderTask {private static final Loggerlog = LoggerFactory.getLogger(CloseOrderTask.class);@Autowiredprivate 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负载均衡配置、常用策略、场景及特点
- 轮询(默认)
- 权重
- ip hash
- url hash(第三方)
- fail(第三方)
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