导航:首页 > 编程语言 > java任务分发

java任务分发

发布时间:2025-07-09 06:26:08

A. 分布式定时任务调度框架实践

分布式任务调度框架几乎是每个大型应用必备的工具,本文介绍了任务调度框架使用的需求背景和痛点,对业界普遍使用的开源分布式任务调度框架的使用进行了探究实践,并分析了这几种框架的优劣势和对自身业务的思考。

一、业务背景

1.1 为什么需要使用定时任务调度

(1)时间驱动处理场景: 整点发送优惠券,每天更新收益,每天刷新标签数据和人群数据。

(2)批量处理数据: 按月批量统计报表数据,批量更新短信状态,实时性要求不高。

(3)异步执行解耦: 活动状态刷新,异步执行离线查询,与内部逻辑解耦。

1.2 使用需求和痛点

(1)任务执行监控告警能力。

(2)任务可灵活动态配置,无需重启。

(3)业务透明,低耦合,配置精简,开发方便。

(4)易测试。

(5)高可用,无单点故障。

(6)任务不可重复执行,防止逻辑异常。

(7)大任务的分发并行处理能力。

二、开源框架实践与 探索

2.1 java 原生 Timer 和

ScheledExecutorService

2.1.1 Timer使用

Timer缺陷:

由于上述缺陷,尽量不要使用Timer, idea中也会明确提示,使用ScheledThreadPoolExecutor替代Timer 。

2.1.2 ScheledExecutorService使用

ScheledExecutorService对于Timer的缺陷进行了修补,首先ScheledExecutorService内部实现是ScheledThreadPool线程池,可以支持多个任务并发执行。

对于某一个线程执行的任务出现异常,也会处理,不会影响其他线程任务的执行,另外ScheledExecutorService是基于时间间隔的延迟,执行不会由于系统时间的改变发生变化。

当然,ScheledExecutorService也有自己的局限性:只能根据任务的延迟来进行调度,无法满足基于绝对时间和日历调度的需求。

2.2 Spring Task

2.2.1 Spring Task 使用

spring task 是spring自主开发的轻量级定时任务框架,不需要依赖其他额外的包,配置较为简单。

此处使用注解配置

2.2.2 Spring Task缺陷

Spring Task 本身不支持持久化,也没有推出官方的分布式集群模式,只能靠开发者在业务应用中自己手动扩展实现,无法满足可视化,易配置的需求。

2.3 永远经典的 Quartz

2.3.1 基本介绍

Quartz框架是Java领域最着名的开源任务调度工具,也是目前事实上的定时任务标准,几乎全部的开源定时任务框架都是基于Quartz核心调度构建而成。

2.3.2 原理解析

核心组件和架构

关键概念

(1) Scheler :任务调度器,是执行任务调度的控制器。本质上是一个计划调度容器,注册了全部Trigger和对应的JobDetail, 使用线程池作为任务运行的基础组件,提高任务执行效率。

(2) Trigger :触发器,用于定义任务调度的时间规则,告诉任务调度器什么时候触发任务,其中CronTrigger是基于cron表达式构建的功能强大的触发器。

(3) Calendar :日历特定时间点的集合。一个trigger可以包含多个Calendar,可用于排除或包含某些时间点。

(4) JobDetail :是一个可执行的工作,用来描述Job实现类及其它相关的静态信息,如Job的名称、监听器等相关信息。

(5) Job :任务执行接口,只有一个execute方法,用于执行真正的业务逻辑。

(6) JobStore :任务存储方式,主要有RAMJobStore和JDBCJobStore,RAMJobStore是存储在JVM的内存中,有丢失和数量受限的风险,JDBCJobStore是将任务信息持久化到数据库中,支持集群。

2.3.3 实践说明

(1)关于Quartz的基本使用

(2)业务使用要满足动态修改和重启不丢失, 一般需要使用数据库进行保存。

(3)组件化

(4)扩展

2.3.4 缺陷和不足

(1)需要把任务信息持久化到业务数据表,和业务有耦合。

(2)调度逻辑和执行逻辑并存于同一个项目中,在机器性能固定的情况下,业务和调度之间不可避免地会相互影响。

(3)quartz集群模式下,是通过数据库独占锁来唯一获取任务,任务执行并没有实现完善的负载均衡机制。

2.4 轻量级神器 XXL-JOB

2.4.1 基本介绍

XXL-JOB是一个轻量级分布式任务调度平台,主打特点是平台化,易部署,开发迅速、学习简单、轻量级、易扩展,代码仍在持续更新中。

主要提供了任务的动态配置管理、任务监控和统计报表以及调度日志几大功能模块,支持多种运行模式和路由策略,可基于对应执行器机器集群数量进行简单分片数据处理。

2.4.2 原理解析

2.1.0版本前核心调度模块都是基于quartz框架,2.1.0版本开始自研调度组件,移除quartz依赖 ,使用时间轮调度。

2.4.3 实践说明

详细配置和介绍参考官方文档。

2.4.3.1 demo使用:

@JobHandler(value="offlineTaskJobHandler") ,实现业务逻辑即可。(注:此次引入了bbo,后文介绍)。

(滑动可查看)

示例2:分片广播任务。

(滑动可查看)

2.4.3.2 整合bbo

(1)引入bbo-spring-boot-starter和业务facade jar包依赖。

(滑动可查看)

(2)配置文件加入bbo消费端配置(可根据环境定义多个配置文件,通过profile切换)。

(滑动可查看)

(3)代码中通过@Reference注入facade接口即可。

(滑动可查看)

(4)启动程序加入@EnableDubboConfiguration注解。

(滑动可查看)

2.4.4 任务可视化配置

内置了平台项目,方便了开发者对任务的管理和执行日志的监控,并提供了一些便于测试的功能。

2.4.5 扩展

(1)任务监控和报表的优化。

(2)任务报警方式的扩展,比如加入告警中心,提供内部消息,短信告警。

(3)对实际业务内部执行出现异常情况下的不同监控告警和重试策略。

2.5 高可用 Elastic-Job

2.5.1 基本介绍

Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。

Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。

Elastic-Job-Cloud使用Mesos + Docker的解决方案,额外提供资源治理、应用分发以及进程隔离等服务。

可惜的是已经两年没有迭代更新记录。

2.5.2 原理解析

2.5.3 实践说明

2.5.3.1 demo使用

(1)安装zookeeper,配置注册中心config,配置文件加入注册中心zk的配置。

(滑动可查看)

(滑动可查看)

(2)配置数据源config,并配置文件中加入数据源配置。

(滑动可查看)

(滑动可查看)

(3)配置事件config。

(滑动可查看)

(4)为了便于灵活配置不同的任务触发事件,加入ElasticSimpleJob注解。

(滑动可查看)

(5)对配置进行初始化。

(滑动可查看)

(6)实现 SimpleJob接口,按上文中方法整合bbo, 完成业务逻辑。

(滑动可查看)

2.6 其余开源框架

(1) Saturn :Saturn是唯品会开源的一个分布式任务调度平台,在Elastic Job的基础上进行了改造。

(2) SIA-TASK :是宜信开源的分布式任务调度平台。

三、优劣势对比和业务场景适配思考

业务思考:

四、结语

对于并发场景不是特别高的系统来说,xxl-job配置部署简单易用,不需要引入多余的组件,同时提供了可视化的控制台,使用起来非常友好,是一个比较好的选择。希望直接利用开源分布式框架能力的系统,建议根据自身的情况来进行合适的选型。

附:参考文献

高可用架构

改变互联网的构建方式

B. 用Java SwingWorker类来创建进度条

SwingWorker类是Java Swing库中用于执行异步任务的核心组件,它能够使得开发者在主线程中保持界面的响应性,同时执行耗时操作,避免阻塞GUI。SwingWorker类实现了RunnableFuture接口,使得它可以提供执行结果,并支持并发任务的处理。

SwingWorker类有两大核心方法:doInBackground()和publish()。doInBackground()方法在后台线程中执行,主要处理耗时的业务逻辑,而publish()方法则用于发布部分结果,触发EDT(事件分发线程)调用process()方法更新UI。

EDT线程执行的process()方法处理publish()方法传入的中间结果,并在UI上显示。这种机制确保了任务的执行和UI的更新在不同线程间有序进行,避免了线程安全问题,并提高了用户体验。

SwingWorker提供了execute()、get()、isDone()和cancel()方法,分别用于提交任务、获取结果、检查任务状态和取消任务,这些方法使得任务管理变得简单且高效。

利用SwingWorker展示进度条的关键在于,通过不断调用setValue(int value)方法更新JProgressBar组件,使其反映任务的执行进度。当任务在doInBackground()方法中执行时,每完成一部分工作,就通过publish()方法将部分结果发送给EDT线程,EDT线程则在process()方法中更新JProgressBar的值。

以BarDemo.java为例,该类通过SwingWorker与EDT线程的协作,动态更新进度条,展示写文件任务的进度。当用户按下“Begin”按钮触发ActionEvent事件,ActionListener会在EDT线程中创建并执行一个ProgressBarHandler任务,该任务在doInBackground()方法中执行写文件操作,并通过publish()方法更新进度。EDT线程在process()方法中根据接收到的中间结果更新进度条。当doInBackground()方法执行完毕,SwingWorker会调用done()方法,向用户显示任务完成的消息。

通过这种方式,BarDemo类能够实时地向用户展示任务的执行状态,提高程序的可操作性和用户友好性,使得复杂任务的执行过程变得可视化、可控。

阅读全文

与java任务分发相关的资料

热点内容
python编写加减乘车程序 浏览:699
python离线安装numpy 浏览:708
xplore解压软件怎么设置 浏览:990
ios反编译混淆代码查看 浏览:315
云计算优化算法 浏览:422
手机头条安装文件夹 浏览:580
网吧服务器怎么分配机子 浏览:826
什么是反编译程序器 浏览:31
pdf完整版下载 浏览:707
linux查看磁盘大小命令 浏览:841
python字母画人物 浏览:668
程序员512g电脑够用吗 浏览:442
自适应式首页源码 浏览:505
python能写app吗 浏览:884
鸟哥的linux私房菜网盘 浏览:337
微信浏览过图片在电脑哪个文件夹 浏览:81
怎样编译一个表 浏览:78
嘉兴前端程序员私活网站推荐 浏览:466
帝都程序员作品 浏览:833
苹果62个app怎么退出一个 浏览:943