推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

分布式解决方案:redis分布式任务调度包

   2023-06-18 网络整理佚名1240
核心提示:使用redis分布式锁,为定时任务唯一指定的key加锁,并设置锁超时时间。是一个开源的作业调度包,能够运行在几乎任何java项目中,小到单机应用,大到电商系统。将任务定义成java组件,能够执行几乎任何你定义的事情。Job负责定义需要执行的任务,负责调度策略,负责将二者组合。启用的分布式任务调度处理,只需如下两个步骤,程序无需修改

原文链接

想法:

1、使用redis分布式锁为定时任务锁定唯一指定的key,并设置锁定超时时间。 当触发定时任务时,通过setNX(key, value)方法锁定唯一键。 如果当前key不存在,则放入缓存并返回true。 通过(key,)设置锁超时时间,结束定时任务方法后跳出执行。 当第二个服务任务进入,设置锁时,发现锁已经存在于缓存中,返回false,不跳转到执行定时任务的方法。

检查是否执行成功:setNX(key, value)以定时任务唯一指定的id为key,value开始时间和时间戳。 比如定时任务在8:00执行,然后在8:30设置一个检测任务,获取定时任务的时间戳,并做差值,如果差值大于30分钟,则说明8点task还没有执行完,就释放了锁。 少于 30 分钟将不予处理。

package com.ayx..redis.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils {
    private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);
    @Autowired
    private RedisTemplate redisTemplate;
	 
    public  boolean tryLock(String key, Object value, long timeout) {
        //底层原理就是Redis的setnx方法
        boolean isSuccess = redisTemplate.opsForValue().setIfAbsent(key, value);
        if (isSuccess) {
			//设置分布式锁的过期时间
            redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
        }
        return isSuccess;
    }

package com.ayx.test;
import com.xjb.redis.utils.RedisUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Component
public class RedisLockTest {
    private static Logger logger = LoggerFactory.getLogger(RedisLockTest.class);
    @Autowired
    RedisUtils redisUtils;
    String redisKey = "demo-RedisLockTest-isRun";
    //单位为秒  默认三分钟
    private long redis_default_expire_time = 60 * 3;
     @Scheduled(cron = "0 */1 * * * ?")
    public void init() throws InterruptedException {
        //-------------上分布式锁开始-----------------
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        //获取本机ip
        String ip = addr.getHostAddress();
        //默认上锁时间为五小时
        //此key存放的值为任务执行的ip,
        // redis_default_expire_time 不能设置为永久,避免死锁
        boolean lock = redisUtils.tryLock(redisKey, ip, redis_default_expire_time);
        logger.info("============本次聚类定时任务开始==============");
        if (lock) {
            logger.info("============获得分布式锁成功=======================");
            //TODO 开始执行任务 执行结束后需要释放锁
            run();
            //释放锁
            redisUtils.del(redisKey);
            logger.info("============释放分布式锁成功=======================");
        } else {
            logger.info("============获得分布式锁失败=======================");
            ip = (String) redisUtils.get(redisKey);
            logger.info("============{}机器上占用分布式锁,聚类任务正在执行=======================", ip);
            logger.info("============本次聚类定时任务结束==============");
            return;
        }
    }
    public void run() throws InterruptedException {
        logger.info("执行中");
        Thread.sleep(1000 * 60 * 2);
        logger.info("执行结束");
    }
}

2.每个定时任务作业都有一个唯一的id。 当发现该作业正在运行时,其他机器将不会调度该作业。

分布式解决方案

介绍

它是一个开源的作业调度包,几乎可以在任何java项目中运行,从小型独立应用程序到大型电子商务系统。 可以创建非常简单的计划,也可以创建包含十个、百个、千个甚至一万个任务的复杂计划。 将任务定义为几乎可以执行您定义的任何内容的 Java 组件。 还支持许多企业级功能,例如 JTA 和集群。 核心是,Job,。 Job 负责定义需要执行的任务,负责调度策略,并将两者结合起来。

分布式解决方案

启用分布式任务调度流程只需以下两步,程序无需修改

在数据库中创建所需的表。 这些表是自己维护的,用来保存数据和维护程序的运行状态。 这些表对程序员是透明的,不需要关心,创建好表即可。

在项目的src下添加.文件,配置集群相关操作。

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON