当前位置: 首页 > article >正文

Java定时任务的三重境界:从单机心跳到分布式协调

《Java定时任务的三重境界:从单机心跳到分布式协调》
本文将以生产级代码标准,揭秘Java定时任务从基础API到分布式调度的6种实现范式,深入剖析ScheduledThreadPoolExecutor与Quartz Scheduler的线程模型差异,并给出各方案的性能压测数据容错设计要点


一、单机模式下的三大兵器谱(适用场景与风险预警)

1. Timer的墓碑级缺陷
Timer timer = new Timer();
timer.schedule(new TimerTask() {@Overridepublic void run() {// 一旦抛出异常,整个Timer线程终止!if(new Random().nextBoolean()) {throw new RuntimeException("模拟任务故障");}System.out.println("Timer task executed");}
}, 1000, 2000);  // 延迟1秒,周期2秒

致命缺陷

  • 单线程调度导致任务堆积(前序任务延迟影响后续)
  • 未捕获异常直接导致线程终止(需手动try-catch)
  • 系统时钟变化敏感(依赖绝对时间调度)
2. ScheduledThreadPoolExecutor工业级方案
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(() -> {try {// 使用线程池隔离风险if(new Random().nextBoolean()) {throw new RuntimeException("任务异常但线程池存活");}System.out.println(Thread.currentThread().getName() + "执行任务");} catch (Exception e) {// 异常处理逻辑}
}, 1, 2, TimeUnit.SECONDS);

核心优势

  • 线程池复用机制(避免频繁创建销毁)
  • 支持相对时间调度(不受系统时间回拨影响)
  • 任务异常隔离(单任务失败不影响整体)
3. Spring @Scheduled注解的隐藏陷阱
@Configuration
@EnableScheduling
public class SpringTaskConfig {@Scheduled(fixedRate = 2000)public void cronTask() {// 默认单线程执行所有@Scheduled方法!System.out.println("Spring task: " + Thread.currentThread().getName());}// 解决方案:配置线程池@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(5);scheduler.setThreadNamePrefix("spring-task-");return scheduler;}
}

必知要点

  • 默认使用单线程执行器(需显式配置线程池)
  • cron表达式与fixedRate的调度策略差异
  • 与@Async结合实现异步调度

二、分布式环境下的高阶战法(CAP原则下的取舍)

1. 数据库悲观锁方案(MySQL行锁示例)
@Scheduled(fixedDelay = 10000)
public void distributedTask() {// 获取数据库连接(需独立数据源)try(Connection conn = dataSource.getConnection()) {conn.setAutoCommit(false);// 使用SELECT FOR UPDATE获取排他锁PreparedStatement stmt = conn.prepareStatement("SELECT id FROM schedule_lock WHERE task_name='report' FOR UPDATE");if(stmt.executeQuery().next()) {// 执行核心业务逻辑generateDailyReport();// 释放锁(事务提交自动释放)conn.commit();}} catch (SQLException e) {// 异常处理}
}

适用场景

  • 中小规模集群(3节点以下)
  • 对任务执行间隔要求不严格
  • 已有MySQL环境快速落地
2. Redis RedLock分布式锁(Redisson实现)
@Scheduled(cron = "0 0 3 * * ?")
public void redisDistributedTask() {RLock lock = redissonClient.getLock("dailyReportLock");try {// 尝试加锁,最多等待10秒,锁持有30秒if(lock.tryLock(10, 30, TimeUnit.SECONDS)) {generateDailyReport();}} finally {lock.unlock();}
}

关键技术点

  • 时钟漂移对RedLock算法的影响
  • 锁续期机制(watchdog线程)
  • 避免锁永久持有的容错设计
3. 分布式任务调度中间件(XXL-JOB架构解析)
// XXL-JOB的Executor端配置
@XxlJob("dailyReportJob")
public void xxlJobHandler() {// 自动获取分片参数int shardIndex = XxlJobHelper.getShardIndex();int shardTotal = XxlJobHelper.getShardTotal();processShardData(shardIndex, shardTotal);
}

平台优势

  • 可视化任务管理(执行记录、报警配置)
  • 动态分片处理(海量数据并行处理)
  • 故障转移与重试策略

三、生产级定时任务设计规范(血的教训总结)

  1. 幂等性设计
// 使用状态机+数据库唯一约束
public void processOrderTask() {List<Order> orders = orderDao.findByStatus(OrderStatus.PENDING);orders.forEach(order -> {if(orderDao.compareAndSetStatus(order.getId(), OrderStatus.PENDING, OrderStatus.PROCESSING)) {// 处理订单}});
}
  1. 监控埋点三要素
@Around("@annotation(scheduled)")
public Object monitorTask(ProceedingJoinPoint pjp) {String taskName = pjp.getSignature().getName();Metrics.counter("scheduled.task.start", "name", taskName).increment();try {return pjp.proceed();} catch (Throwable e) {Metrics.counter("scheduled.task.error", "name", taskName).increment();throw e;} finally {Metrics.counter("scheduled.task.end", "name", taskName).increment();}
}
  1. 弹性调度策略
# Spring弹性配置示例
resilience4j.retry:instances:reportTask:maxAttempts: 3waitDuration: 5000msretryExceptions:- java.net.ConnectException

架构选型决策树
在这里插入图片描述
掌握这些技术细节后,开发者应根据业务规模(QPS量级)、团队运维能力、任务重要性(是否允许漏执行)等维度进行综合决策。建议在预生产环境进行调度压力测试,重点验证任务堆积时的线程池拒绝策略与熔断机制的有效性。

相关文章:

Java定时任务的三重境界:从单机心跳到分布式协调

《Java定时任务的三重境界&#xff1a;从单机心跳到分布式协调》 本文将以生产级代码标准&#xff0c;揭秘Java定时任务从基础API到分布式调度的6种实现范式&#xff0c;深入剖析ScheduledThreadPoolExecutor与Quartz Scheduler的线程模型差异&#xff0c;并给出各方案的性能压…...

响应压缩导致的接口请求response没有响应体问题排查

目录 一、背景二、排查过程三、解决方法四、学习与思考-响应压缩&#xff08;一&#xff09;可能原因&#xff08;二&#xff09;深入排查&#xff08;三&#xff09;注意 一、背景 接口发布到测试环境&#xff0c;测试同学说没有数据 二、排查过程 1、本地用相同的参数、相…...

【Linux网络】手动部署并测试内网穿透

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

java项目之在线购物系统(源码+文档)

项目简介 在线购物系统实现了以下功能&#xff1a; 使用在线购物系统的用户分管理员和用户两个角色的权限子模块。 管理员所能使用的功能主要有&#xff1a;主页、个人中心、用户管理、商品分类管理、商品信息管理、系统管理、订单管理等。 用户可以实现主页、个人中心、我的…...

【设计模式】C++ 单例模式总结与最佳实践

1. 单例模式简介 单例模式&#xff08;Singleton Pattern&#xff09; 是软件开发中常见的设计模式之一&#xff0c;主要用于 确保某个类只有一个实例&#xff0c;并提供一个全局访问点。常见的使用场景包括&#xff1a; 日志管理&#xff1a;全局唯一的日志记录器。数据库连…...

OO_Unit1

第一次作业 UML类图 代码复杂度分析 其中Expr中的toString方法认知复杂度比较高&#xff0c;主要源于多层条件嵌套和分散的字符串处理逻辑&#xff0c;重构时可重点关注这两部分的解耦。 代码量分析 1.”通用形式“ 我觉得我的设计的最大特点就是“通用形式”&#xff0c;具…...

重要重要!!fisher矩阵元素有什么含义和原理; Fisher 信息矩阵的形式; 得到fisher矩阵之后怎么使用

fisher矩阵元素有什么含义和原理 目录 fisher矩阵元素有什么含义和原理一、对角线元素( F i , i F_{i,i} Fi,i​)的含义与原理二、非对角线元素( F i , j F_{i,j} Fi,j​)的含义与原理Fisher 信息矩阵的形式矩阵的宽度有位置权重数量决定1. **模型参数结构决定矩阵维度**2.…...

[已解决]jupyter notebook报错 500 : Internal Server Error及notebook闪退

jupyter notebook出现如上图的报错&#xff0c;可以在黑色窗口中检查是为什么报错。 我检查发现是nbconvert导致的问题&#xff0c;卸载重装nbconvert。 但是这时候出现&#xff0c;jupyter notebook闪退问题。jupyter的黑色窗口出现一秒钟就没了。 在Anaconda Prompt中检查ju…...

2025年渗透测试面试题总结- 某亭-安全研究员(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、SQL注入过滤单引号绕过方法 二、MySQL报错注入常用函数 三、报错注入绕WAF 四、MySQL写文件函数…...

Redis分布式锁如何实现——简单理解版

目录 前言 满足条件 加锁之后产生的问题 避免死锁的方法 Lua脚本实现避免释放其他锁 看门狗判断过期 扩展 Lua脚本 Redission 前言 在如今开发的某些项目中&#xff0c;多个进程必须以互斥的方式独占共享资源&#xff0c;这时用分布式锁是最直接有效的&#xff0c;分布式…...

数字化转型驱动卫生用品安全革新

当315晚会上晃动的暗访镜头揭露卫生巾生产车间里漂浮的异物、纸尿裤原料仓中霉变的碎屑时&#xff0c;这一触目惊心的场景无情地撕开了“贴身安全”的遮羞布&#xff0c;暴露的不仅是部分企业的道德缺失&#xff0c;更凸显了当前检测与监管体系的漏洞&#xff0c;为整个行业敲响…...

北京南文观点:品牌如何抢占AI 认知的 “黄金节点“

在算法主导的信息洪流中&#xff0c;品牌正在经历一场隐蔽的认知权争夺战&#xff0c;当用户向ChatGPT咨询"哪家新能源车企技术最可靠"时&#xff0c;AI调取的知识图谱数据源将直接决定品牌认知排序。南文乐园科技文化&#xff08;北京&#xff09;有限公司&#xff…...

分布式(一):CAPBASE理论

1 CAP理论 1.1 简介 CAP也就是Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;、Partition Tolenrance&#xff08;分区容错性&#xff09;这三个单词首字母组合。 在理论计算机科学中&#xff0c;CAP定理&#xff08;CAP theorem&…...

自适应柔顺性策略:扩散引导控制中学习近似的柔顺

24年10月来自斯坦福大学和 TRI 的论文“Adaptive Compliance Policy: Learning Approximate Compliance for Diffusion Guided Control”。 柔顺性在操作中起着至关重要的作用&#xff0c;因为它可以在不确定的情况下平衡位置和力的并发控制。然而&#xff0c;当今的视觉运动策…...

python中所有内置类型

文章目录 数值类型序列类型集合类型映射类型布尔类型空类型代码汇总 在 Python 中&#xff0c;数据类型可分为内置数据类型和用户自定义数据类型。内置数据类型是 Python 解释器直接支持的类型 数值类型 整数&#xff08;int&#xff09;&#xff1a;表示整数&#xff0c;可正…...

​「Java-API帮助文档」

「Java-API帮助文档」&#xff0c;链接&#xff1a;https://pan.quark.cn/s/d7ced3b48f33 java.applet提供创建 applet 所必需的类和 applet 用来与其 applet 上下文通信的类。java.awt包含用于创建用户界面和绘制图形图像的所有类。java.awt.color提供用于颜色空间的类。java…...

1204. 【高精度练习】密码

文章目录 题目描述输入输出样例输入样例输出数据范围限制CAC代码 题目描述 人们在做一个破译密码游戏&#xff1a; 有两支密码棒分别是红色和蓝色&#xff0c;把红色密码棒上的数字减去蓝色 密码棒上的数字&#xff0c;就是开启密码锁的密码。 现已知密码棒上的数字位数不超过…...

SVN简明教程——下载安装使用

SVN教程目录 一、开发中的实际问题二、简介2.1 版本控制2.2 Subversion2.3 Subversion的优良特性2.4 工作原理2.5 SVN基本操作 三、Subversion的安装与配置1. 服务器端程序版本2. 下载源码包3. 下载二进制安装包4. 安装5. 配置版本库① 为什么要配置版本库&#xff1f;② 创建目…...

“智改数转”新风口,物联网如何重构制造业竞争力?

一、政策背景 为深化制造业智能化改造、数字化转型、网络化联接&#xff0c;江苏省制定了《江苏省深化制造业智能化改造数字化转型网络化联接三年行动计划&#xff08;2025&#xff0d;2027年&#xff09;》&#xff0c;提出到2027年&#xff0c;全省制造业企业设备更新、工艺…...

从数据洪流到智能洞察:人工智能如何解锁大数据的价值?

引言&#xff1a;数据洪流时代&#xff0c;企业的机遇与挑战 在这个信息爆炸的时代&#xff0c;数据正以前所未有的速度增长。IDC预测&#xff0c;全球数据量将在未来几年内持续飙升&#xff0c;企业每天都会产生海量的用户行为数据、市场交易数据、设备传感数据等。理论上&…...

蓝桥杯 之 数论

文章目录 习题质数找素数 LCM报数游戏 快速幂数字诗意 组合数与错位排序小蓝与钥匙 同余取模 数论&#xff0c;就是一些数学问题&#xff0c;蓝桥杯十分喜欢考察&#xff0c;常见的数论的问题有&#xff1a;取模&#xff0c;同余&#xff0c;大整数分解&#xff0c;素数&#x…...

SpringBoot的启动原理?

大家好&#xff0c;我是锋哥。今天分享关于【SpringBoot的启动原理&#xff1f;】面试题。希望对大家有帮助&#xff1b; SpringBoot的启动原理&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Boot的启动原理主要是通过 SpringApplication 类来…...

从零开始搭建向量数据库:基于 Xinference 和 Milvus 的文本搜索实践

引言 在 AI 和大数据时代&#xff0c;向量数据库正成为处理非结构化数据&#xff08;如文本、图像&#xff09;的利器。最近&#xff0c;我尝试用 Xinference 和 Milvus 搭建一个简单的文本搜索系统&#xff0c;从读取本地文本文件到实现交互式查询和高亮显示匹配结果&#xf…...

音视频系列——Websockets接口封装为Http接口

模型服务示例&#xff1a;实时语音转文本服务 本示例展示一个支持双协议&#xff08;WebSocket流式接口HTTP同步接口&#xff09;的语音转文本模型服务&#xff0c;并提供将WebSocket接口封装为HTTP接口的代码实现。 一、服务架构设计 #mermaid-svg-nw0dMZ4uKfS4vGZR {font-fa…...

scrapy入门(深入)

Scrapy框架简介 Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据&#xff0c;只需要实现少量的代码&#xff0c;就能够快速的抓取。 新建项目 (scrapy startproject xxx)&#xff1a;新建一个新的…...

docker模拟Dos_SYN Flood拒绝服务攻击 (Ubuntu20.04)

目录 ✅ 一、实验环境准备&#xff08;3 个终端&#xff09; &#x1f449; 所以最终推荐做法&#xff1a; 2️⃣ 配置 seed-attacker 为攻击者&#xff0c;开启 telnet 服务&#xff1a; 3️⃣ 配置 victim-10.9.0.5 为受害者服务器&#xff0c;开启 telnet 客户端并监听&…...

使用 Ansys Fluent 评估金属管道腐蚀

金属管道的维护和完整性在石油和天然气、石化和供水等各个行业中都至关重要。腐蚀对这些管道构成了重大威胁&#xff0c;可能导致泄漏、结构故障和环境危害。Ansys Fluent 提供了一个强大的平台来建模和分析金属管道腐蚀。 腐蚀是一种自然过程&#xff0c;金属材料会因与环境发…...

firefly经典蓝牙和QProcess、QFileSystemWatcher记录

QProcess 默认不会启动一个 shell 来解析命令,而是直接调用操作系统的系统调用来启动外部程序。也就是通过fork一个子线程或者exec一个子进程来执行命令。 QProcess的参数模式 QProcess 需要明确指定命令的可执行文件路径或参数列表。 如果命令是一个可执行文件的路径…...

基于PySide6的CATIA自动化工具开发实战——空几何体批量清理系统

一、功能概述 本工具通过PySide6构建用户界面&#xff0c;结合PyCATIA库实现CATIA V5的自动化操作&#xff0c;提供两大核心功能&#xff1a; ​空几何体清理&#xff1a;智能识别并删除零件文档中的无内容几何体&#xff08;Bodies&#xff09;​空几何图形集清理&#xff1…...

Blender配置渲染设置并输出动画

在Blender中&#xff0c;渲染设置和渲染动画的选项位于不同的面板中。以下是具体步骤&#xff1a; 渲染设置 渲染设置用于配置输出格式、分辨率、帧率等参数。 打开右侧的 属性面板&#xff08;按 N 键可切换显示&#xff09;。 点击 “输出属性” 选项卡&#xff08;图标是…...