自学内容网 自学内容网

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

需求

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

解决方案

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

以下方案基于springboot+redis

1. 引入redisson

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.17.5</version>
</dependency>

2. 写RedissonConfig bean

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. 启动定时任务时增加获取锁逻辑

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){
            }
        }

原文地址:https://blog.csdn.net/qq32933432/article/details/144356853

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!