谷粒商城-定时任务

一、定时任务

1、cron表达式

在这里插入图片描述

在这里插入图片描述
在spring中只写6个字段,分别是秒分时日月周,中间用空格隔开,每一个字段也有特殊的写法,上面已经介绍过了,这里不再赘述

注意:

  1. 周的写法一定注意,Quartz定时框架中中1代表周日,7代表周六,这里采用外国人的周计算方法,所以一定分清楚;但是spring中1代表周一,7代表周日,这是和中国人的一样,不过cron表达式做法是一样的;
  2. 看Cron表达式应该从最后一个非通配符字段开始看起,然后从右往左看,具有通配符的地方代表every每一个都是如此,当然它是被cron表达式右边一点的字段限制着;
  3. 如何避免定时任务阻塞在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2、cron示例

在这里插入图片描述

cron表达式生成器:https://cron.qqe2.com

二、具体使用

直接上代码好说明:

/**
 * 秒杀商品定时上架配置
 */
@EnableScheduling // 开启定时任务
@EnableAsync // 开启异步任务
@Configuration
public class ScheduledConfig {

    @Autowired
    private SeckillService seckillService;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 上架明天的秒杀商品
     */
    @Scheduled(cron = "0 30 5 * * ?")
    public void uploadSeckillGoods() {
        // 添加分布式锁,避免同一时间内多个机器同时往redis中添加相关信息
        RLock lock = redissonClient.getLock(SeckillConstant.UPLOAD_LOCK);
        lock.lock();
        try{
            // 执行业务代码
            seckillService.uploadSeckillGoods();
        } finally {
            // 解除分布式锁
            lock.unlock();
        }
    }

    /**
     * 清除前一天的库存相关信息,包括商品、库存,还要把使用之后的库存更新到数据库中
     */
    @Scheduled(cron = "0 0 5 * * ?")
    public void cleanSeckillSkuInfo() {
        // 添加分布式锁,避免同一时间内多个机器同时去清理
        RLock lock = redissonClient.getLock(SeckillConstant.CLEAN_LOCK);
        lock.lock();
        try{
            // 执行业务代码
            seckillService.cleanSeckillSkuInfo();
        } finally {
            // 解除分布式锁
            lock.unlock();
        }
    }
}

@EnableScheduling开启定时任务是必不可少的,但是这个定时任务用到的线程池中只有一个线程,所以相当于是阻塞式的,但是异步任务不应该是阻塞式的,因此我们需要让定时任务异步执行,所以就需要加上@EnableAsync注解,除此之外还需要在application.yml中添加定时任务中用到的异步任务相关的线程池配置,如下所示:

# 定时任务中用到的异步任务使用到的线程池配置
spring:
  task:
    execution:
      pool:
        core-size: 5
        max-size: 9
        queue-capacity: 100000
        keep-alive: 10s

这样才能真正让定时任务异步执行,另外这几个值我们可以复用,比如我们其他地方还需要使用线程池,那我们就可以将这几个配置用上也是可以的

最后还要说一下里面的分布式锁,这是因为异步执行的时候不能让多个线程同时执行同一个定时任务,因此我们需要分布式锁,然后我们还要保证幂等性,不能让商品上架之后再次上架吧,所以我们需要在所使用的方法中进行幂等性判断,比如:

// 查询最近1天的秒杀商品信息集合
List<SeckillSessionEntityVo> seckillVos = couponFeignService.getSeckillGoods();
// 将秒杀商品信息缓存到redis中
if (seckillVos != null && seckillVos.size() > 0) {
	*****************
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值