悠悠楠杉
SpringBoot整合ElasticJob实现分布式定时任务全攻略
Spring Boot整合ElasticJob实现分布式定时任务全攻略
关键词:Spring Boot定时任务、ElasticJob分布式调度、Zookeeper配置、动态任务管理
描述:本文详细讲解如何在Spring Boot项目中整合ElasticJob实现高可用的分布式定时任务,包含完整代码示例和避坑指南。
一、为什么选择ElasticJob?
在传统Spring定时任务(@Scheduled)遇到分布式场景时,会出现任务重复执行的问题。我们最近在电商项目中就遇到了订单超时检查任务在多个实例上重复触发的情况。
ElasticJob作为当当网开源的分布式调度解决方案,提供了:
- 分布式协调(基于Zookeeper)
- 任务分片
- 失效转移
- 可视化运维界面
二、环境准备
2.1 必备组件
bash
开发环境
- JDK 1.8+
- Maven 3.6+
- Zookeeper 3.6.2(单机模式测试可用)
2.2 Maven依赖
xml
三、实战整合步骤
3.1 配置Zookeeper连接
yaml
application.yml
elasticjob:
reg-center:
server-lists: localhost:2181
namespace: elasticjob-demo
3.2 实现第一个定时任务
java
@Component
public class OrderTimeoutJob implements SimpleJob {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void execute(ShardingContext context) {
// 实际项目中建议添加分布式锁
logger.info("开始执行订单超时检查");
// 分片处理逻辑示例
switch(context.getShardingItem()) {
case 0:
checkTimeoutOrders(0, 5000); // 处理ID 0-5000的订单
break;
case 1:
checkTimeoutOrders(5001, 10000);
break;
}
}
private void checkTimeoutOrders(int start, int end) {
// 实现具体业务逻辑
}
}
3.3 任务配置类
java
@Configuration
public class JobConfig {
@Bean(initMethod = "init")
public SpringJobScheduler orderJobScheduler(
OrderTimeoutJob job,
CoordinatorRegistryCenter regCenter) {
JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder(
"orderTimeoutJob", // 任务名称
"0/30 * * * * ?", // 每30秒执行
2 // 分片数
).build();
SimpleJobConfiguration jobConfig = new SimpleJobConfiguration(
coreConfig,
job.getClass().getName()
);
return new SpringJobScheduler(
job,
regCenter,
LiteJobConfiguration.newBuilder(jobConfig).build()
);
}
}
四、高阶功能实现
4.1 动态修改任务配置
java
@RestController
@RequestMapping("/jobs")
public class JobController {
@Autowired
private CoordinatorRegistryCenter registryCenter;
@PostMapping("/update-cron")
public String updateCron(@RequestParam String jobName,
@RequestParam String newCron) {
JobConfigurationAPI configAPI = new JobConfigurationAPI(registryCenter);
configAPI.updateJobConfiguration(jobName, newCron);
return "定时规则已更新";
}
}
4.2 任务失败告警
通过实现JobErrorHandler
接口:
java
@Component
public class CustomJobErrorHandler implements JobErrorHandler {
@Override
public void handleException(String jobName, Throwable cause) {
// 发送邮件/短信告警
AlertService.send("任务【"+jobName+"】执行异常:" + cause.getMessage());
}
}
五、生产环境注意事项
- Zookeeper集群:生产环境至少3节点,避免单点故障
- 监控对接:通过
JobEventConfiguration
对接Prometheus - 日志隔离:建议为ElasticJob单独配置日志文件
- 版本升级:注意2.x到3.x的API变化较大
六、性能优化建议
- 合理设置分片数(建议等于应用实例数)
- 避免单次任务处理数据量过大
- 对于长时间任务启用
failover
配置
踩坑记录:我们曾因未设置合理的分片策略,导致某个节点负载过高。后来通过
shardingItemParameters
实现按业务ID取模分片解决了问题。
完整示例代码已上传GitHub:项目地址