分布式定时任务解决方案(redis版)

需求

当我们项目在服务器上部署了多个节点时我们期望只能有一个节点开跑

解决方案

目前有很多的方案,比如用xxljob等定时任务框架,但如果是小项目,也不想搭那么多服务,毕竟服务多维护成本也高,应该怎么弄呢?

以下方案基于springboot+redis

1. 引入redisson

xml 复制代码
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.17.5</version>
</dependency>

2. 写RedissonConfig bean

java 复制代码
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {  
    
  @Value("${spring.redis.host}")
  private String redisHost;  
  
  @Value("${spring.redis.port}")  
  private int redisPort;

  @Value("${spring.redis.password}")
  private String redisPassword;
  
  @Bean
  public RedissonClient redissonClient() {
    Config config = new Config();
    config.useSingleServer().setAddress(String.format("redis://%s:%d", redisHost, redisPort)).setPassword(redisPassword);
    return Redisson.create(config);
  }  
}

3. 启动定时任务时增加获取锁逻辑

java 复制代码
RedissonClient redissonCache = SpringUtils.getBean(RedissonClient.class);
        String key = "jobName: " + job.getJobName();
        //定时任务执行周期较短,为防止数据重复修改,加入锁
        RLock lock = redissonCache.getLock(key);
        try {
            // 执行任务
            log.info("任务准备执行,尝试获取锁 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());

            // 尝试获取锁并设定锁的过期时间
            boolean acquired = false;
            try {
                acquired = lock.tryLock(0, LOCK_KEY_TIME, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                log.info("tryLock异常", e);
            }
            if (acquired) {
                log.info("任务获取锁成功,开始执行 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
                // todo 此处写定时任务执行方法
            }
        }catch (Exception e) {
            log.info("任务执行失败 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
            log.error("任务执行异常  - :", e);
        } finally {
            // 释放锁
            try {
                log.info("准备释放锁 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
                lock.unlock();
                log.info("释放锁成功 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
            }catch (Exception e){
            }
        }
相关推荐
hxj..13 天前
【分布式】Redis分布式锁
redis·分布式·中间件·redis分布式锁·redis锁
_whitepure4 个月前
分布式锁详解
java·分布式·分布式锁·redis分布式锁·zookeeper分布式锁
ProjectNo1 年前
Redis分布式锁进阶源码分析
redis·分布式·分布式锁·redis分布式锁
studyday11 年前
【中间件篇-Redis缓存数据库04】Redis底层原理持久化、分布式锁
数据库·缓存·中间件·redis持久化’·redis分布式锁
xxkfz1 年前
Spring Boot 整合xxl-job实现分布式定时任务
xxl-job·分布式定时任务