目录
第16章 使用Spring schedule+Redission实现分布式任务调度
第15章 Redission的使用
15.1 总览
- Redission的介绍
- Redission的集成
15.2 Redission介绍
略。
15.3 Redission集成
不仅要添加Redission依赖,还需要添加fastxml依赖。
<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>
15.4 Redission使用
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;
/**
* Created by geely
*/
@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);
}
}
}
第16章 使用Spring schedule+Redission实现分布式任务调度
16.1 总览
- Redission的锁
- wait_time的坑
16.2 定时任务使用Redission
@Component
@Slf4j
public class CloseOrderTask {
@Autowired
private IOrderService iOrderService;
@Autowired
private RedissonManager redissonManager;
@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,5, 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分布式锁释放锁");
}
}
}
16.3 wait_time的坑
lock.tryLock(0,5, TimeUnit.SECONDS)
在获取锁的时候,需要设置等待时间和保持时间。如果等待时间设置的不合适,可能进程1获取了锁并执行了定时任务后,还没有达到进程2获取锁的等待时间,那么进程2就会获取锁并将任务又执行一遍。
所以有两个解决办法,一是将wait_time设为0。而是调试来评估任务执行的大致时间,设置一个更小的等待时间,虽然还是有风险。