Spring Schedule + Redisson 构建分布式任务调度
相当于对 V3 版本的 Spring Session + Redis(分布式锁)的一个封装。
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-avro</artifactId> <version>2.9.0</version> </dependency>
package com.mmall.common; import com.mmall.util.PropertiesUtil; import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.config.Config; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Component @Slf4j public class RedissonManager { private Config config = new Config(); private Redisson redisson = null; public Redisson getRedisson() { return redisson; } private static String redis1Ip = PropertiesUtil.getProperty("redis1.ip"); private static Integer redis1Port = Integer.parseInt(PropertiesUtil.getProperty("redis1.port")); private static String redis2Ip = PropertiesUtil.getProperty("redis2.ip"); private static Integer redis2Port = Integer.parseInt(PropertiesUtil.getProperty("redis2.port")); @PostConstruct private void init(){ try { config.useSingleServer().setAddress(new StringBuilder().append(redis1Ip).append(":").append(redis1Port).toString()); redisson = (Redisson) Redisson.create(config); log.info("初始化Redisson结束"); } catch (Exception e) { log.error("redisson init error",e); } } }
@Scheduled(cron="0 */1 * * * ?") public void closeOrderTaskV4(){ RLock lock = redissonManager.getRedisson().getLock(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK); boolean getLock = false; try { if(getLock = lock.tryLock(0, 50, TimeUnit.SECONDS)){ log.info("Redisson获取到分布式锁:{},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); }else{ log.info("Redisson没有获取到分布式锁:{},ThreadName:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName()); } } catch (InterruptedException e) { log.error("Redisson分布式锁获取异常",e); } finally { if(!getLock){ return; } lock.unlock(); log.info("Redisson分布式锁释放锁"); } }
- 注意 tryLock 方法,第一个参数 wait_time 设置为 0,因为在这里不知道注释掉的那个关闭订单的业务逻辑代码里面需要执行多久,一般情况也很难检测出具体是多少,因为跟很多因素相关,所以干脆设置为 0,一定不会出问题。