模仿网站 素材哪里来营销推广文案
常用定时任务框架
-
JDK 自带的
ScheduledExecutorService
- 适用于轻量级定时任务,基于线程池实现。
- API 简单,适用于小规模任务调度。
-
Quartz
- 强大的 Java 任务调度框架,支持 Cron 表达式、分布式集群、持久化等。
- 适用于复杂调度场景,如动态任务管理、任务持久化等。
-
Spring Task
- Spring 提供的轻量级定时任务方案,支持
@Scheduled
注解,简洁易用。 - 适用于简单的定时任务,不支持集群和分布式调度。
- Spring 提供的轻量级定时任务方案,支持
-
XXL-JOB
- 轻量级分布式任务调度框架,支持集群、动态管理任务、任务日志、失败重试等功能。
- 适用于互联网企业的大规模定时任务场景。
-
Elastic-Job
- 基于 Zookeeper 的分布式任务调度框架,支持分片、失效转移、任务高可用等特性。
- 适用于大规模分布式任务调度,如电商、金融等业务场景。
-
PowerJob
- 基于 Spring Boot 开发的分布式任务调度框架,支持分布式、秒级调度、任务依赖等功能。
- 适用于现代分布式任务管理,支持 Web 可视化管理。
大数据相关
-
Azkaban
- 由 LinkedIn 开源的批处理任务调度系统,适用于大数据任务调度。
- 主要用于 Hadoop 任务的调度,支持 DAG 依赖关系管理。
-
Airflow
- Apache 旗下的工作流调度系统,支持 Python 任务编排,DAG 任务依赖管理。
- 适用于数据工程、机器学习等复杂任务调度。
-
Oozie
- Hadoop 生态中的工作流调度系统,主要用于 Hadoop 任务调度。
- 适用于大数据 ETL 任务管理。
运维 & DevOps
-
Kubernetes CronJob
- 适用于 Kubernetes 集群环境的定时任务,支持容器化任务调度。
- 适用于微服务架构下的定时任务。
-
Crontab(Linux 自带)
- 适用于简单的系统级定时任务调度,如 Shell 脚本、数据同步等。
选择建议
- 轻量级:
Spring Task
/ScheduledExecutorService
- 单机复杂调度:
Quartz
- 分布式调度:
XXL-JOB
/Elastic-Job
/PowerJob
- 大数据任务调度:
Airflow
/Azkaban
/Oozie
- K8s 云原生:
Kubernetes CronJob
分布式定时任务框架
如果你的项目被 多个相同实例的 Pod 复制 并部署在 Kubernetes 集群中,那么使用普通的 @Scheduled
或 ScheduledExecutorService
就会导致 每个 Pod 都会执行同一个定时任务,可能会产生 重复任务执行 的问题。为了解决这个问题,你可以选择 支持分布式调度 的定时任务框架,主要有以下几种推荐方案:
1. Elastic-Job(推荐)
- 适用场景:适用于 微服务架构,可基于 Zookeeper 进行任务分片,实现分布式调度。
- 特点:
- 分片执行:不同 Pod 执行任务的不同部分,避免重复执行。
- 任务失效转移:某个 Pod 宕机后,任务会自动转移给其他 Pod 继续执行。
- 支持高可用:基于 Zookeeper 进行任务协调,防止重复执行。
- 适用于:
- 高并发业务,如订单对账、数据同步、日志清理等。
- 需要保证每个任务只执行一次,或按分片方式执行的场景。
2. XXL-JOB
- 适用场景:适用于 Spring Boot + 集群环境,提供一个 调度中心 统一管理任务,避免重复执行。
- 特点:
- 基于调度中心(Admin)统一管理定时任务。
- 任务分片:可配置多个 Pod 执行不同的任务片段,防止重复执行。
- 失败重试:任务失败后可自动重试。
- 可视化管理:Web 界面配置任务,支持动态修改。
- 适用于:
- 需要 Web 可视化管理任务的场景。
- 希望任务分布式执行,并能动态调整任务执行策略。
3. PowerJob
- 适用场景:适用于 现代云原生架构,支持 秒级任务调度、分布式任务执行。
- 特点:
- 支持 Standalone、Worker、Server 三种模式。
- 多种执行模式:单机、广播、MR、MapReduce 等。
- 动态扩展:Worker 增加时自动均衡任务负载。
- 可视化管理:类似 XXL-JOB,可动态修改任务配置。
- 适用于:
- 云原生环境(Kubernetes 部署),任务需要动态扩缩容。
- 需要支持复杂任务依赖的调度场景。
4. Kubernetes CronJob(适用于简单定时任务)
- 适用场景:适用于 Kubernetes 环境,需要 周期性执行的任务,如:
- 订单定期清理
- 数据库备份
- 日志归档
- 特点:
- K8s 原生支持,直接通过
CronJob
配置调度任务。 - 任务隔离:每次任务都会创建一个新的 Pod,适合一次性任务。
- 无法做任务分片,不适用于高并发、复杂任务调度。
- K8s 原生支持,直接通过
- 适用于:
- 简单的、无需分片的定时任务(比如每天凌晨执行数据备份)。
- 无需对任务执行状态进行复杂管理的场景。
5. Quartz + DB 锁(适用于持久化任务调度)
- 适用场景:如果你的任务需要存储到数据库,并且希望 只有一个实例 触发定时任务。
- 方法:
- Quartz 任务存储到 数据库(JDBC Store)。
- 任务执行前 数据库加锁,保证任务不会被多个 Pod 并发执行。
- 适用于:
- 需要保证任务持久化,并防止重复执行。
- 不想引入 Zookeeper、调度中心等额外依赖的情况下。
推荐方案
方案 | 适用场景 | 任务去重 | 分布式支持 | 备注 |
---|---|---|---|---|
Elastic-Job | 高并发、任务分片、任务转移 | ✅ | ✅ 基于 Zookeeper | 适用于微服务和任务均衡 |
XXL-JOB | 大规模分布式任务调度 | ✅ | ✅ 统一调度中心 | 适用于企业级任务管理 |
PowerJob | 云原生 + 任务编排 | ✅ | ✅ 支持 MapReduce | 适用于复杂任务调度 |
K8s CronJob | 简单定时任务 | ❌ | ❌ | 适用于周期性任务,如数据清理 |
Quartz + DB 锁 | 持久化任务调度 | ✅ | ❌ | 适用于小规模任务,防止重复 |
最终选择
如果你的 定时任务是分布式环境下的关键任务:
✅ 推荐 Elastic-Job
或 XXL-JOB
,避免重复执行,并支持任务分片。
如果你的 定时任务是云原生环境:
✅ 推荐 PowerJob
,可以动态扩缩容,适配 Kubernetes。
如果你的 定时任务是单一周期性任务:
✅ 推荐 Kubernetes CronJob
,原生支持,简单好用。
如果你的 定时任务需要持久化,并防止重复执行:
✅ 推荐 Quartz + DB 锁
,适用于少量任务的环境。
Elastic-Job 示例代码
下面是 Elastic-Job 在分布式集群环境下的完整示例代码,基于 Spring Boot + Zookeeper,实现了 分布式定时任务调度。
功能概述
- 采用
Spring Boot + Elastic-Job-Lite
实现分布式定时任务。 - 任务注册到 Zookeeper,保证 多个实例(Pod)不会重复执行同一任务,可实现 任务分片。
- 适用于 Kubernetes、Docker Swarm 及 普通分布式集群环境。
1. 引入依赖
在 pom.xml
中添加 Elastic-Job 相关依赖:
<dependencies><!-- Elastic-Job 核心 --><dependency><groupId>org.apache.shardingsphere.elasticjob</groupId><artifactId>elasticjob-lite-spring-boot-starter</artifactId><version>3.0.2</version></dependency><!-- Zookeeper 客户端 --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.5.0</version></dependency><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
2. 配置 Zookeeper
在 application.yml
中配置 Elastic-Job 连接 Zookeeper:
spring:application:name: elastic-job-demoelasticjob:reg-center:server-lists: zk-host:2181 # 替换为你的 Zookeeper 地址namespace: elastic-job-demo # 在 Zookeeper 创建的命名空间jobs:demoJob:cron: "0/10 * * * * ?" # 每 10 秒执行一次sharding-total-count: 3 # 任务分片总数,多个实例共同执行任务overwrite: true # 是否覆盖旧任务
3. 编写定时任务
新建 分片任务,继承 SimpleJob
,实现 execute()
方法:
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.springframework.stereotype.Component;@Component
public class MyElasticJob implements SimpleJob {@Overridepublic void execute(ShardingContext shardingContext) {// 获取当前分片编号int shardingItem = shardingContext.getShardingItem();String jobName = shardingContext.getJobName();// 模拟不同分片处理不同数据switch (shardingItem) {case 0:System.out.println("【分片 0】执行任务:" + jobName);break;case 1:System.out.println("【分片 1】执行任务:" + jobName);break;case 2:System.out.println("【分片 2】执行任务:" + jobName);break;default:System.out.println("【未知分片】执行任务:" + jobName);}}
}
4. 注册任务
创建 ElasticJobConfig
,将任务注册到 ElasticJob
:
import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.ScheduleJobBootstrap;
import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.OneOffJobBootstrap;
import org.apache.shardingsphere.elasticjob.lite.api.listener.ElasticJobListener;
import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ElasticJobConfig {private final ZookeeperRegistryCenter regCenter;private final MyElasticJob myElasticJob;public ElasticJobConfig(ZookeeperRegistryCenter regCenter, MyElasticJob myElasticJob) {this.regCenter = regCenter;this.myElasticJob = myElasticJob;}@Beanpublic ScheduleJobBootstrap initElasticJob() {JobConfiguration jobConfig = JobConfiguration.newBuilder("myElasticJob", 3).cron("0/10 * * * * ?") // 每 10 秒执行.overwrite(true) // 覆盖旧任务.build();return new ScheduleJobBootstrap(regCenter, myElasticJob, jobConfig);}
}
5. 配置 Zookeeper 注册中心
创建 ZookeeperConfig
以连接 Zookeeper:
import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperConfiguration;
import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ZookeeperConfig {@Bean(initMethod = "init")public ZookeeperRegistryCenter regCenter() {return new ZookeeperRegistryCenter(new ZookeeperConfiguration("zk-host:2181", "elastic-job-demo"));}
}
6. 运行多个 Pod 进行集群测试
方式 1:本地多个实例
分别启动多个 Spring Boot
实例:
java -jar target/elastic-job-demo.jar --server.port=8081
java -jar target/elastic-job-demo.jar --server.port=8082
java -jar target/elastic-job-demo.jar --server.port=8083
查看日志:
- 任务分片 0 在
8081
执行- 任务分片 1 在
8082
执行- 任务分片 2 在
8083
执行
方式 2:Kubernetes 部署
编写 deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:name: elastic-job-demo
spec:replicas: 3 # 启动 3 个实例selector:matchLabels:app: elastic-job-demotemplate:metadata:labels:app: elastic-job-demospec:containers:- name: elastic-jobimage: your-docker-repo/elastic-job-demo:latestports:- containerPort: 8080env:- name: ZK_HOSTvalue: "your-zk-cluster:2181"
部署到 Kubernetes:
kubectl apply -f deployment.yaml
7. 任务执行结果
在多个 Pod 中查看日志
kubectl logs -f elastic-job-demo-xxxx
示例输出:
【分片 0】执行任务:myElasticJob
【分片 1】执行任务:myElasticJob
【分片 2】执行任务:myElasticJob
特点:
- 多个 Pod 共同执行任务,不会重复执行相同的任务
- 任务会按分片编号进行分配
- Pod 宕机时,任务会自动迁移到其他 Pod
总结
方案 | 说明 |
---|---|
Elastic-Job + Zookeeper | 适用于 分布式定时任务,确保任务 不重复执行 |
任务分片 | 多个 Pod 共同执行任务,各自处理不同分片 |
Kubernetes 兼容 | 适用于微服务架构,支持动态扩缩容 |
适用场景:
- 分布式数据清理
- 订单对账
- 定期同步数据库数据
- 日志归档
XXL-JOB
下面是 XXL-JOB 在 分布式集群场景下 执行定时任务的完整示例代码,基于 Spring Boot + MySQL 实现。
功能概述
- 使用 XXL-JOB 框架调度分布式任务,保证 多个实例 不会重复执行同一任务。
- 配置 JobHandler,任务在集群中分片执行。
- 使用 MySQL 存储任务执行信息,支持 分布式集群部署,避免任务重复执行。
1. 引入依赖
在 pom.xml
中添加 XXL-JOB 和 Spring Boot 相关依赖:
<dependencies><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- XXL-JOB --><dependency><groupId>com.xxl.job</groupId><artifactId>xxl-job-core</artifactId><version>2.3.0</version></dependency><!-- Spring Boot Starter for XXL-JOB --><dependency><groupId>com.xxl.job</groupId><artifactId>xxl-job-spring-boot-starter</artifactId><version>2.3.0</version></dependency><!-- MySQL Driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency>
</dependencies>
2. 配置 XXL-JOB
在 application.yml
中配置 XXL-JOB 的相关信息:
xxl:job:admin:addresses: http://admin-server:8080/xxl-job-admin # XXL-JOB Admin 的地址executor:appname: xxl-job-demo # 执行器应用名称ip: 0.0.0.0 # 允许所有IP访问port: 9999 # 执行器端口logpath: /data/applogs/xxl-job/ # 执行日志路径logretentiondays: 30 # 执行日志保留天数
3. 配置 XXL-JOB Admin
XXL-JOB Admin 需要先进行安装和启动,可以在官网 XXL-JOB GitHub 找到安装步骤。
4. 编写定时任务(JobHandler)
新建一个 JobHandler,继承 XXLJob
并重写 execute()
方法:
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.handler.IJobHandler;
import org.springframework.stereotype.Component;@JobHandler(value = "demoJobHandler")
@Component
public class DemoJobHandler extends IJobHandler {@Overridepublic ReturnT<String> execute(String param) throws Exception {// 业务逻辑,比如进行数据清理或定时任务等System.out.println("执行定时任务: " + param);return ReturnT.SUCCESS;}
}
在这里,demoJobHandler
是 JobHandler 的名字,需要在 XXL-JOB Admin 配置。
5. 配置 XXL-JOB 执行器
创建 XxlJobConfig
配置类,完成 XXL-JOB 执行器的配置:
import com.xxl.job.core.executor.XxlJobExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class XxlJobConfig {@Beanpublic XxlJobExecutor xxlJobExecutor() {XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();xxlJobExecutor.setAdminAddresses("http://admin-server:8080/xxl-job-admin");xxlJobExecutor.setAppname("xxl-job-demo");xxlJobExecutor.setIp("0.0.0.0");xxlJobExecutor.setPort(9999);xxlJobExecutor.setLogPath("/data/applogs/xxl-job/");xxlJobExecutor.setLogRetentionDays(30);return xxlJobExecutor;}
}
6. 配置 XXL-JOB Admin 创建任务
登录 XXL-JOB Admin 后,进行以下配置:
- 创建调度器:在 XXL-JOB Admin 中点击 Job Group,创建一个新的 调度器。
- 添加任务:在 Job 页面中,点击 添加任务,配置任务名、执行器类型(选择
demoJobHandler
)、分片信息等。
7. 配置任务分片执行
在 XXL-JOB Admin 中,配置分片策略,例如:
- 分片总数:3(表示任务将分配给 3 个不同的实例执行)
- 任务执行器的分片项:XXL-JOB 会自动将任务按分片项分配给不同的执行器实例。
例如,如果有 3 个执行器实例,则会将任务的 3 个分片(0、1、2)分别分配给 3 个实例执行,确保不同的实例执行不同的任务。
8. 启动项目并执行任务
启动 Spring Boot
项目,确保 XXL-JOB Admin 已经部署并且任务已经配置。
- 启动 Spring Boot 项目:
mvn spring-boot:run
- 任务自动执行:项目启动后,XXL-JOB 执行器会自动向 XXL-JOB Admin 注册,并开始执行定时任务。
- 查看任务执行日志:可以在 XXL-JOB Admin 中查看任务的执行日志。
9. 扩展功能:动态任务调度
如果需要动态调整任务执行策略(如调整任务的分片数等),可以通过 XXL-JOB Admin 动态调整任务配置。
例如,在 XXL-JOB Admin 中:
- 修改任务的 Cron表达式,例如设置成每 30 秒执行一次;
- 修改 分片数,如果集群规模扩大,可以修改任务的 分片总数。
10. 总结
方案 | 说明 |
---|---|
XXL-JOB | 适用于 分布式任务调度,支持 多实例任务分片执行 |
任务分片 | 多个实例共同执行任务,避免重复执行任务,确保高可用性 |
MySQL 存储 | 任务执行信息存储在数据库,支持持久化、任务调度管理 |
Web UI 管理 | 支持通过 XXL-JOB Admin Web 界面进行任务管理、调度 |
适用场景:
- 分布式任务调度
- 定时任务执行
- 数据同步
- 日志清理
使用 XXL-JOB 可以在分布式集群中实现高效、可靠的定时任务调度,并且通过 MySQL 存储任务执行状态,确保任务不丢失,执行状态可追踪。