集群模式下的定时任务与Redis分布式锁

业务场景:在电商项目中,往往会有这样的一个功能设计,当用户下单后一段时间没有付款,系统就会在超时后关闭该订单。

通常我们会做一个定时任务每分钟来检查前半小时的订单,将没有付款的订单列表查询出来,然后对订单中的商品进行库存的恢复,然后将该订单设置为无效。

比如我们这里使用Spring Schedule的方式做一个定时任务:

注:打开Spring Schedule 的自动注解扫描,在Spring配置中添加<task:annotation-driven/>

@Component
@Slf4j
public class CloseOrderTask {
   
   

    @Autowired
    private IOrderService iOrderService;

    @Scheduled(cron = "0 */1 * * * ? ")
    public void closeOrderTaskV1() {
        log.info("定时任务启动");
        //执行关闭订单的操作
        iOrderService.closeOrder();
        log.info("定时任务结束");
    }
}

在单服务器下这样执行并没有问题,但是随着业务量的增多,势必会演进成集群模式,在同一时刻有多个服务执行一个定时任务就会带来问题,首先是服务器资源的浪费,同时会带来业务逻辑的混乱,如果定时任务是做的数据库操作将会带来很大的风险。

Redis分布式锁

下面分析一下分布式情况下定时任务的解决方案

通常使用Redis作为分布式锁来解决这类问题,Redis分布式锁流程如下:

Redis分布式锁v1版本:
//注意:以下为了测试方便,定时时间都设置为10s
@Scheduled(cron = "0/10 * * * * ? ")
    public void closeOrderTaskV1() {
        log.info("定时任务启动");
        long lockTime = 5000;//5秒
        Long lockKeyResult = RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK, String.valueOf(System.currentTimeMillis() + lockTime));

        //如果获得了分布式锁,执行关单业务
        if (lockKeyResult != null && lockKeyResult.intValue() == 1) {
            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
        }else {
            log.info("没有获得分布式锁");
        }
        log.info("定时任务结束================================");
    }

//关闭订单,并释放锁
    private void closeOrder(String lockName) {
        Red
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带着天使反上帝 - Kaybee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值