集群多机部署定时任务使用redis分布式锁

定时任务如果不进行控制,就会在集群环境下重复运行,除了使用qrtz或者类似xxl job等方式进行控制的,还可以使用redis分布式锁进行控制,获得锁对象的才可以进行业务操作

代码实现:

public void incrNewsViewCount() {
    Boolean flag = redisTemplate.opsForValue().setIfAbsent("news_count_incr_switch", "lock",60*60*3, TimeUnit.SECONDS);
    if(flag){
        log.info("获取redis锁开始进行业务操作");
        try{
            List<BaseNewsInfo> needIncrViewCountNewsList=baseNewsInfoMapper.selectNeedIncrViewCountList();
            if(CollectionUtils.isEmpty(needIncrViewCountNewsList)){
                return;
            }
            needIncrViewCountNewsList.stream().forEach(news->{
                Integer targetViewCount = news.getTargetViewCount();
                Integer initMinute = news.getInitMinute();
                Integer totalViewCount = news.getTotalViewCount();
                Integer diffViewCount=targetViewCount-totalViewCount;
                //取出redis值进行+n操作
                Integer redisViewCount=null;
                if(redisClient.get("view_count_" + news.getNewsId())!=null){
                    redisViewCount = Ints.tryParse(redisClient.get("view_count_" + news.getNewsId()).toString());
                }
                for(int i=1;i<=initMinute*60;i++){
                    try {
                        Thread.sleep(1000);
                        int step=diffViewCount%(initMinute*60)==0?diffViewCount/(initMinute*60):diffViewCount/(initMinute*60)+1;
                        log.info("redis 新增步长:{}",step);
                        redisClient.incr("view_count_" + news.getNewsId(),step);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                BaseNewsInfo baseNewsInfo=new BaseNewsInfo();
                baseNewsInfo.setNewsId(news.getNewsId());
                baseNewsInfo.setTotalViewCount(Ints.tryParse(redisClient.get("view_count_" + news.getNewsId()).toString()));
                baseNewsInfoMapper.updateByPrimaryKeySelective(baseNewsInfo);
            });
        }finally {
            //释放锁资源
            redisTemplate.delete("news_count_incr_switch");
        }
    }
}

当业务代码执行完毕后 需要在最后finally,释放掉锁资源,以便后续可再次获取锁对象,否则只能等到过期后才能执行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力终会有回报

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

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

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

打赏作者

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

抵扣说明:

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

余额充值