多服务环境下定时任务重复执行问题解决方案

2023-11-06

        当一个服务部署在多台服务器上时,定时任务可能出现多次执行的情况,就是每个服务上执行一次。有以下两种思路,一是固定死只有某服务器执行定时任务,二是随机暂停几秒,某一服务执行了,其他就不再执行。

1、固定某一个服务器作为执行定时任务的机器

        通过配置文件或者其他方式,在一个服务器懂的时候可以用参数动态配置他是是否执行程序中的定时任务。

        该方式存在一定的弊端,一个项目部署到到多个服务,本意是提高服务的负载和可用性,如果将定时任务固定设置在一个服务上, 那么该服务宕机后,定时任务就无法执行,存在少执行定时任务的可能性。

步骤:

        配置文件中设置参数值,确定是否开启定时任务

# 定时抽取corn表达式
schedule-corn: "0 30 07 * * ?"
# 是否开启定时任务 0不开启,1开启
schedule-tag: 1

        代码中获取参数并校验,改服务是否开启

//获取配置文件中的参数值
@Value("${schedule-tag}")
private Integer ScheduleTag;


@Scheduled(cron = "${schedule-corn}")
public void Schedule(){
    if (Objects.equals("1",ScheduleTag)){
        //执行定时任务的内容
    }
}

2、借助Redis的过期机制

        为你的定时器在Redis中定义一个键值对,可以用项目名称和服务器ip,执行任务前先从Redis中读取键,若没有值代表任务未被执行,同样的该台机器先更新redis,再触发定时任务。由于Redis存在过期机制,因此可以设置过期时间保证下次判断正常。

        该模式下也存在一定问题,当Redis宕机时,所有的服务都能够执行定时任务;当多个服务的系统时间不相同时,若Redis键值对的过期时间过小,也有可能出现重复执行的情况。

步骤:        

        将前置逻辑封装为一个方法

/**
 * 定时任务前置逻辑
 * @param expiryTime 过期时间
 * @param key 
 * @return
 */
public boolean preTask(String key,Long expiryTime) {
    // 随机停1-10秒。
    int randomInt = ThreadLocalRandom.current().nextInt(1, 10);
    try {
        Thread.sleep(randomInt * 1000L);
    } catch (InterruptedException e) {
        log.info(e.getMessage());
    }
    //获取服务所在服务器的名字
    String name = SystemUtil.getHostInfo().getName();
    //判断Redis是否存在该key,若不存在则保存参数中的键值对,并设置过期时间
    Boolean absent = redisTemplate.opsForValue().setIfAbsent(key, name + port, expiryTime, TimeUnit.SECONDS);
    if (Objects.isNull(absent) || !absent) {
        String namePort = (String) redisTemplate.opsForValue().get(key);
        log.info("本实例不执行此轮 {} 定时任务。由 {} 执行。", key, namePort);
        return false;
    }
    log.info("本实例开始执行 {} 定时任务。", key);
    return true;
}

        定时任务调用前置逻辑

//静态变量,作为该定时任务的key
private static final String EXTRACT_SCHEDULE_KEK = "TIME_TASK:EXTRACT_SCHEDULE_KEK";


@Scheduled(cron = "${schedule-corn}")
public void extractSchedule(){
    // 多实例限制
    boolean preTask = redisTaskUtil.preTask(EXTRACT_SCHEDULE_KEK, 3600L);
    if (preTask){
        //定时任务的内容
    }
}

    

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多服务环境下定时任务重复执行问题解决方案 的相关文章

随机推荐

  • 【Flask】Flask-SQLAlchemy的增删改查(CRUD)操作

    Flask实战的经验总结 有问题随时与我联系 一起学习交流 喜欢的话点个三连吧 Flask项目数据库相关文章还有 Flask项目sqlite数据库操作 代码实现 Flask SQLAlchemy 为 Flask 提供了一个 SQLAlche
  • 5-9 Java Number & Math 类

    Java Number Math 类 Number 所有的包装类都是抽象类 Number 的子类 Number 类属于 java lang 包 public class Test public static void main String
  • CloudCompare 二次开发(7)——直通滤波

    目录 一 概述 二 代码集成 三 结果展示 本文由CSDN点云侠原创 原文链接 爬虫网站自重 一 概述 直通滤波的算法原理见 PCL 直通滤波器 基于PCL将直通滤波集成到CloudCompare软件中 二 代码集成 1 mainwindo
  • 曼哈顿距离

    曼哈顿距离 Manhattan distance 又称为城市街区距离或L1距离 是两点在南北方向和东西方向上的距离之和 对于二维平面上的两个点A x1 y1 和B x2 y2 它们的曼哈顿距离可以表示为 d x1 x2 y1 y2 其中 a
  • 二叉排序树的合并(C语言)

    二叉排序树的合并其实有好多方法了 反正就是把元素插入进去就好了 大不了两颗树都不建直接新建一个二叉排序树 函数也不是很难 如下 include
  • React(三)自定义render处理map的虚拟节点和diff算法

    React 一 JSX概念和实例 Zoie ting的博客 CSDN博客 React 二 实现自定义createElement和render Zoie ting的博客 CSDN博客 一 map的渲染 根据前两篇的实践 基本把JSX渲染出来了
  • jsp调整字体大小font_jsp中CSS如何设置字体大小、斜体及颜色

    我想在自己的网站中应用这个菜单 但是菜单的字体是固定的 应该怎样改变字体的大小 这个字体太小了 中文显示很难看 先解这个问题 修改这两个CSS即可 style1 font size 30px style4 font size 24px fo
  • 使用HTML和CSS完成网页导航模块的制作步骤和方法

    小编本人从事IT培训教育行业多年 在教授学生网页设计课程的时候 尤其是到CSS部分的时候 学生总是很难理解 大部分学生上手慢 针对这个问题 小编本人在教学的时候 将网页设计分模块进行讲解 今天就来给大家分享一下如何使用HTML和CSS完成网
  • 时间序列预测——双向LSTM(Bi-LSTM)

    本文展示了使用双向LSTM Bi LSTM 进行时间序列预测的全过程 包含详细的注释 整个过程主要包括 数据导入 数据清洗 结构转化 建立Bi LSTM模型 训练模型 包括动态调整学习率和earlystopping的设置 预测 结果展示 误
  • ipcfg报错_编译出错信息解析

    1 SRC WEB WEBPOST C 599 warning C280 ipcfg unreferenced local variable 定义了 但是没有使用 就会有这个警告 一般来说 出现这种情况则表示可以删除警告中所指的变量 2 S
  • redis学习:BitMap

    使用位存储 信息状态只有 0 和 1 这个适合哪种记录某些状态只有两种状态的 比如说成绩及没及格 是男是女 不考虑跨性别的 上班迟没迟到 是或者不是这种 Bitmap是一串连续的2进制数字 0或1 每一位所在的位置为偏移 offset 在b
  • java.lang.IllegalStateException: Failed to convert message:‘‘ to outbound message.

    java lang IllegalStateException Failed to convert message GenericMessage payload 4a76a1ea 9bab 4305 a7f9 26b63e113a19 he
  • jmeter 聚合数据_性能测试连载 (37)性能测试数据错误率分析

    概述 性能测试脚本跑完了之后 我们除了要收集瓶颈数据 还有分析错误数据 通常一套脚本跑完 错误类型不止一种 但是jmeter只会在聚合报告里面给出一个总体的错误率 错误率 jmeter里的错误率是如何统计的 在返回的数据里面 只要succe
  • 2022上半年

    2022上半年 b a c b 找不同 a 串联公式 并联公式 c b d c 在本地安装的沙都软件和网页被篡改没有之间的联系 a 对于SNAT 是由内网去访问外网的时候进行的地址转换 d b c b c c d b c d b a
  • 实现微信小程序web-view内嵌H5中的下载功能(大文件切片下载)

    实现微信小程序内嵌H5中的下载功能 一 项目场景 难点 解决方案 1 H5微信小程序 a 首先必不可少的是安装jweixin module模块 b 在main js中将依赖绑定 c H5对应页面点击下载时代码为 2 uni app的小程序
  • python+selenium+unittest自动化测试

    python selenium unittest自动化测试详解 Base 基类层 最基础类 供其他文件调用 封装浏览器方法 以方便后面代码的调用 可以二次封装自带的方法 方便调用 其他地方调用基础类的方法 如果需要修改调用地方的方法 只需要
  • 为什么我们要用Spring?

    在之前的文章说说java反射 2 反射的价值我们对java反射的内容有了一定的了解 并且通过反射机制做了一个简单的框架 也算是对于Spring框架的铺垫 接下来了解一下我们使用Spring框架的意义 Spring是一个解决了许多在J2EE开
  • 始料未及的COVID-19、延期的考试、又可以瞎倒腾的喜悦

    Hmmm 真的本来下定决心不要东摸西摸专心功课 但是确实发生了本次人类历史上的大事件 当然可能在以后的日子里这个也就是洒洒水水平 导致了考试的延期 我又再一次的东张西望起来 hmmm 好吧为了庆祝又可以自由活动 特此献上抄来的小程序一篇 以
  • 解决Rosbridge自定义action信息问题

    前言 利用rosbridge开发一个网页版的action客户端 一 rosbridge原理 rosbridge协议 该协议的基本思想是将节点间的分布式通信 改成 client节点 与一个代理节点进行C S通信 然后代理节点再将请求转发给se
  • 多服务环境下定时任务重复执行问题解决方案

    当一个服务部署在多台服务器上时 定时任务可能出现多次执行的情况 就是每个服务上执行一次 有以下两种思路 一是固定死只有某服务器执行定时任务 二是随机暂停几秒 某一服务执行了 其他就不再执行 1 固定某一个服务器作为执行定时任务的机器 通过配