1. SpringTask和XXL-JOB的区别
Spring Task 是 Spring 框架中的一个轻量级任务调度框架,它允许开发者以声明式的方式在 Spring 应用程序中实现定时任务。Spring Task 使用的是 Spring 自身的核心功能,无需依赖其他额外的库。它支持cron表达式,可以方便地设定任务的执行周期。
XXL-JOB 则是一个分布式任务调度平台,由中国人许雪里(Xuxueli)开发。它同样简单易用,并具有丰富的功能,如支持分片广播任务、失败重试、任务依赖等高级特性。XXL-JOB 提供了Web界面,可以用来管理和调度任务,非常适合企业级的任务调度管理。
两者之间的主要区别在于:
-
集成和使用:
- Spring Task 是 Spring 框架的一部分,只需在 Spring 应用中简单配置即可使用。
- XXL-JOB 需要独立部署调度中心,并将客户端集成到现有应用中。
-
适用场景:
- Spring Task 适合于单一应用内的简单任务调度。
- XXL-JOB 适合于分布式环境下的任务调度,特别是当需要中央管理和控制任务执行时。
-
功能和特性:
- Spring Task 提供基本的定时任务功能,适合简单的调度需求。
- XXL-JOB 提供了更多高级特性,如任务分片、子任务依赖、执行结果跟踪等,适合大规模、复杂的任务调度。
-
管理和监控:
- Spring Task 的管理和监控相对简单,通常依赖于Spring Boot Actuator等工具。
- XXL-JOB 提供了完整的任务管理界面,可以方便地监控和控制任务的执行。
2. xxl-job启动
在xxl-job-admin配置数据库的相关信息
任务调度中心的链接(根据自己的ip地址修改localhost,还有端口号)
账号:admin 密码:123456
3. xxl-job的使用
(1)在执行器管理中创建执行器
(2) 在所使用的模块中引入xxl-job的依赖
在父模块中设置xxl-job-core.version为2.3.1
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job-core.version}</version>
</dependency>
在application.yml中配置xxl-job的信息
xxl:
job:
admin:
addresses: http://localhost:8088/xxl-job-admin #任务调度中心地址
executor:
appname: test1 #任务执行器名称
addresss:
ip:
port: 9999 #任务执行器端口号
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
accessToken: default_token
(3)在任务管理中添加任务
JobHandler使用的是对应@XxJob("名称")中的名称,
可以使用CRON表达式或者固定速度设置调度的频率
新建成功后,任务管理中点击操作,启动任务
(4)代码的编写
可以参考xxl-job所给SampleXxlJob的示例代码:
4. xxl-job高级配置
(1)路由策略
XXL-Job 提供了多种执行器路由策略,这些策略决定了当有多个执行器实例时,调度中心如何选择一个执行器来执行任务。以下是各个策略的简要说明:
-
FIRST(第一个):
- 策略会选择列表中的第一个执行器来执行任务。
- 优点:实现简单,适用于执行器性能相近的场景。
- 缺点:可能导致第一个执行器负载较高。
-
LAST(最后一个):
- 策略会选择列表中的最后一个执行器来执行任务。
- 优点:与FIRST相反,可以避免总是由第一个执行器执行任务。
- 缺点:同样可能导致最后一个执行器负载较高。
-
ROUND(轮询):
- 策略会轮流选择执行器来执行任务,实现负载均衡。
- 优点:可以平均分配任务到各个执行器,避免单个执行器过载。
- 缺点:如果执行器性能不一致,可能导致性能较差的执行器成为瓶颈。
-
RANDOM(随机):
- 策略会随机选择一个执行器来执行任务。
- 优点:适用于执行器数量较多且性能相近的场景,可以较好地分散任务。
- 缺点:理论上仍有可能导致某些执行器负载较高。
-
CONSISTENT_HASH(一致性哈希):
- 策略会根据任务ID或参数计算哈希值,选择对应的执行器。
- 优点:可以保证相同参数的任务总是在同一个执行器上执行,适用于有状态的任务。
- 缺点:执行器增减时可能会造成任务重新分配。
- LEAST_FREQUENTLY_USED(最不经常使用):
- 策略会选择使用频率最低的执行器来执行任务。
- 优点:可以更好地利用所有执行器资源。
- 缺点:需要维护每个执行器的使用频率信息。
-
FAILOVER(故障转移):
- 策略会优先选择正常在线的执行器,如果执行器出现故障,任务会转移到其他执行器。
- 优点:提高任务的可靠性,确保任务在某个执行器故障时仍能执行。
- 缺点:可能会增加任务调度的复杂性。
-
BUSYOVER(忙碌转移):
- 策略会优先选择负载较低的执行器,如果执行器忙碌,任务会转移到其他执行器。
- 优点:可以避免将任务调度到已经非常忙碌的执行器上,提高任务响应速度。
- 缺点:需要实时监控执行器的负载情况。
(2)阻塞处理策略
在XXL-Job中,当调度线程池满时,系统提供了三种不同的阻塞处理策略
-
SERIAL_EXECUTION(单机串行):
- 当线程池满时,新的任务将会排队等待,直到有线程空闲出来。这种方式保证了任务的串行执行,即同一时间内只有一个任务在执行。
- 优点:确保任务按照调度顺序执行,不会因为并发执行而产生资源竞争问题。
- 缺点:执行效率较低,因为任务必须等待前一个任务完成才能开始。
-
DISCARD_LATER(丢弃后续调度):
- 当线程池满时,后续的任务将会被丢弃,不会加入到线程池中执行。
- 优点:可以防止系统因为过多的任务而超载。
- 缺点:可能会导致任务执行失败,特别是对于一些重要任务,这可能会造成业务上的影响。
-
COVER_EARLY(覆盖之前调度):
- 当线程池满时,新的任务将会覆盖掉之前等待执行的任务。通常是覆盖掉队列中最早的任务。
- 优点:可以保证最新的任务得到执行,适用于任务时效性要求较高的场景。
- 缺点:可能会导致一些任务永远无法执行,特别是当任务频繁调度时,较早的任务可能会一直被覆盖。
5.xxl-job分片广播(集群)
广播每次调度会向集群中所有执行器发送任务调度,请求中携带分片参数
每个执行器都收到调度请求,同时接收分片参数
分片的序列号从0开始
(1)分片广播的使用
在本机上进行分片广播测试,所添加单点不仅仅要修改端口号,还有xxl-job所执行的端口号
示例代码:
@XxlJob("shardingJobHandler")
public void shardingJobHandler(String param) throws Exception {
// 获取分片参数
ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
int shardIndex = shardingVO.getIndex(); //根据分片的序列号,用于确认执行顺序
int shardTotal = shardingVO.getTotal(); //根据分片的总数
// 根据分片索引和总数执行相应的逻辑
for (int i = shardIndex; i < dataTotal; i += shardTotal) {
// 处理数据
}
}
然后再使用任务管理新建并启动(在任务管理中新建任务时,选择分片广播的路由策略)
(2)分片广播适合的场景:
- 分片任务:10个执行器的集群来处理10w条数据,每台机器需要处理1w条数据,耗时降低10倍
- 广播任务:广播执行器同时运行shell脚本,广播集群节点进行缓存更新等。
总结:广播分片方式不仅可以充分发挥每个执行器的能力,并根据分片参数控制任务是否执行,最终灵活控制了执行器季军分布式处理任务。