2018.8.2 java电商从1到2--chapter15~16 SpringSchedule+Redission实现分布式任务调度

目录

第15章 Redission的使用

15.1 总览

15.2 Redission介绍

15.3 Redission集成

15.4 Redission使用

第16章 使用Spring schedule+Redission实现分布式任务调度

16.1 总览

16.2 定时任务使用Redission

16.3 wait_time的坑


第15章 Redission的使用

15.1 总览

  • Redission的介绍
  • Redission的集成

 

15.2 Redission介绍

略。

 

15.3 Redission集成

不仅要添加Redission依赖,还需要添加fastxml依赖。

1 <dependency> 2 <groupId>org.redisson</groupId> 3 <artifactId>redisson</artifactId> 4 <version>2.9.0</version> 5 </dependency> 6 <dependency> 7 <groupId>com.fasterxml.jackson.dataformat</groupId> 8 <artifactId>jackson-dataformat-avro</artifactId> 9 <version>2.9.0</version> 10 </dependency> 11

 

15.4 Redission使用

1package com.mmall.common; 2 3import com.mmall.util.PropertiesUtil; 4import lombok.extern.slf4j.Slf4j; 5import org.redisson.Redisson; 6import org.redisson.config.Config; 7import org.springframework.stereotype.Component; 8 9import javax.annotation.PostConstruct; 10 11/** 12 * Created by geely 13 */ 14@Component 15@Slf4j 16public class RedissonManager { 17 18 private Config config = new Config(); 19 20 private Redisson redisson = null; 21 22 public Redisson getRedisson() { 23 return redisson; 24 } 25 26 private static String redis1Ip = PropertiesUtil.getProperty("redis1.ip"); 27 private static Integer redis1Port = Integer.parseInt(PropertiesUtil.getProperty("redis1.port")); 28 private static String redis2Ip = PropertiesUtil.getProperty("redis2.ip"); 29 private static Integer redis2Port = Integer.parseInt(PropertiesUtil.getProperty("redis2.port")); 30 31 @PostConstruct 32 private void init(){ 33 try { 34 config.useSingleServer().setAddress(new StringBuilder().append(redis1Ip).append(":").append(redis1Port).toString()); 35 36 redisson = (Redisson) Redisson.create(config); 37 38 log.info("初始化Redisson结束"); 39 } catch (Exception e) { 40 log.error("redisson init error",e); 41 } 42 } 43 44} 45 46

 

第16章 使用Spring schedule+Redission实现分布式任务调度

16.1 总览

  • Redission的锁
  • wait_time的坑

 

16.2 定时任务使用Redission

1@Component 2@Slf4j 3public class CloseOrderTask { 4 5 @Autowired 6 private IOrderService iOrderService; 7 8 @Autowired 9 private RedissonManager redissonManager; 10 11 @Scheduled(cron="0 */1 * * * ?") 12 public void closeOrderTaskV4(){ 13 RLock lock = redissonManager.getRedisson().getLock(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK); 14 boolean getLock = false; 15 try { 16 if(getLock = lock.tryLock(0,5, TimeUnit.SECONDS)){ 17 log.info("Redisson获取到分布式锁:{},ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName()); 18 int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2")); 19 iOrderService.closeOrder(hour); 20 }else{ 21 log.info("Redisson没有获取到分布式锁:{},ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName()); 22 } 23 } catch (InterruptedException e) { 24 log.error("Redisson分布式锁获取异常",e); 25 } finally { 26 if(!getLock){ 27 return; 28 } 29 lock.unlock(); 30 log.info("Redisson分布式锁释放锁"); 31 } 32 } 33 34} 35

 

 

16.3 wait_time的坑

1lock.tryLock(0,5, TimeUnit.SECONDS) 2

在获取锁的时候,需要设置等待时间和保持时间。如果等待时间设置的不合适,可能进程1获取了锁并执行了定时任务后,还没有达到进程2获取锁的等待时间,那么进程2就会获取锁并将任务又执行一遍。

所以有两个解决办法,一是将wait_time设为0。而是调试来评估任务执行的大致时间,设置一个更小的等待时间,虽然还是有风险。

代码交流 2021