ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

使用redis分布式锁解决spring schedule集群部署重复执行问题

2022-02-28 10:30:46  阅读:219  来源: 互联网

标签:info schedule lock redis private key spring logger


产品需求:

对接腾讯云实时音视频,实时拉取腾讯云最新的视频并使用Ffmpeg视频合成。

遇到问题:

由于服务都是集群部署,定时任务会在各个服务器上重复执行,轻则浪费服务器资源,重则造成数据紊乱。

解决方案:

quartz定时任务提供了集群方式,但还需为其创建数据库表。spring schedule可以实现简单轻量级的定时任务,但无法保证只执行一次。
通过和架构师探讨得知,可以使用redis的分布式锁保证spring schedule集群只执行一次。
redis分布式锁是通过setnx命令实现的。该命令的作用是,当往redis中存入一个值时,会先判断该值对应的key是否存在,如果存在则返回0,如果不存在,则将该值存入redis并返回1。根据这个特性,我们在程序中,每次都调用setIfAbsent(该方法是setnx命令的实现)方法,来模拟是否获取到锁,如果返回true,则说明该key值不存在,表示获取到锁;如果返回false,则说明该key值存在,已经有程序在使用这个key值了,从而实现了类似加锁的功能。

@Component
@Configuration
@EnableScheduling
public class AutoConvertTask {
    private static final Logger logger = LoggerFactory.getLogger(AutoConvertTask.class);

    @Autowired
    private RedisTemplate redisTemplate;

    private static final String LOCK = "task-job-lock";

    private static final String KEY = "tasklock";

    @Scheduled(cron = "0 0 0 * * ? ")
    public void autoConvertJob() {
        boolean lock = false;
        try {
            lock = redisTemplate.opsForValue().setIfAbsent(KEY, LOCK);
            logger.info("是否获取到锁:" + lock);
            if (lock) {
                List<GameHistory> historyList = historyService.findTenDaysAgoUntreated();
                for (GameHistory history : historyList) {
                    update(history);
                }
            } else {
                logger.info("没有获取到锁,不执行任务!");
                return;
            }
        } finally {
            if (lock) {
                redisTemplate.delete(KEY);
                logger.info("任务结束,释放锁!");
            } else {
                logger.info("没有获取到锁,无需释放锁!");
            }
        }

    }

}

这就是使用Redis的解决方案,Github上面还有好多使用redis封装成框架的解决方案哦。

标签:info,schedule,lock,redis,private,key,spring,logger
来源: https://blog.csdn.net/chezong/article/details/123175685

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有