[note 8-Redis distributed lock] independently completed the enterprise Java e-commerce website development (server side) from 0

Redis distributed lock

Redis distributed lock command

  • Setnx if and only if the key does not exist. If the given key already exists, setnx does nothing. Setnx is the abbreviation of "set if not exists". Setnx has atomicity.  

  • get set gets the old value first, then sets the new value, and returns the old value of the key, which is atomic. When the key exists but is not of string type, an error is returned; when the key does not exist, nil is returned, which is null in Java.  

  • expire set the validity of the key

  • del delete key

Redis distributed lock flow chart

Redis distributed lock optimized flow chart

Spring Schedule + Redis distributed lock to build distributed task schedule

@Component

@Slf4j

public class CloseOrderTask {

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

    @Autowired

    private IOrderServiceiOrderService;

    @PreDestroy  // Execute delete lock before closing Tomcat to avoid deadlock

    public void delLock(){

RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

    }

// @Scheduled(cron = "0 */1 * *?" ") / / every minute (integer multiple of every minute)

    public void closeOrderTaskV1(){

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

        log.info("Close order scheduled task start");

        iOrderService.closeorder(hour);

        log.info("Close order scheduled task end");

    }

//@ Scheduled(cron = "0 */1 * *?") / / every minute (integer multiple of every minute)

    public void closeOrderTaskV2(){

log.info("Close order scheduled task start");

        // Lock timeout

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

        // Set if no
				
        Long setnxResult= RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout));

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

            //If the return value is 1, it means the setting is successful and the lock is acquired

            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

        }else{

            log.info("No distributed lock obtained:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

        }

        log.info("Close order scheduled task end");

    }

@Scheduled(cron ="0 */1 * * * ?")//Every minute (integral multiple of every minute)

    public void closeOrderTaskV3(){

        log.info("Close order scheduled task start");

        //Lock timeout

        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){

       //If the return value is 1, it means the setting is successful and the lock is acquired

            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

        }else{

           //If the lock is not acquired, continue to judge and determine the time stamp to see whether the lock can be reset and acquired

            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 with the current time stamp again

               //Return the old value of the given key, and judge whether the lock can be obtained by the old value

               //When the key has no old value, that is, when the key does not exist, nil - > get lock is returned

               //Here we set a new value to get the old value

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

                    //Get the lock

                    closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

                }else{

                    log.info("No distributed lock obtained:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

                }

     }else{

               log.info("No distributed lock obtained:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

            }

}

     log.info("Close order scheduled task end");

    }

private void closeOrder(String lockName){

     RedisShardedPoolUtil.expire(lockName,50);//Valid for 5 seconds to prevent deadlock

        log.info("Obtain{} ,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("release{} ,ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());

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

    }

}

Tomcat cluster quick start

Nginx load balancing configuration, common strategies, scenarios and features

  • Poll (default)

  • weight

  • ip hash

  • url hash (third party)

  • fail (third party)

Nginx+Tomcat build cluster

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

Tomcat cluster quick start

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

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

Reference resources:

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

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

Tags: Redis Tomcat Nginx Java

Posted on Tue, 11 Feb 2020 11:39:16 -0500 by zytex