定时任务

定时任务设计

IMS 系统中大量后台任务需要定时执行,如数据同步、报表生成、订单超时处理等。本文介绍定时任务的设计与分布式环境下的避坑指南。

一、简单定时任务

Spring Task

/* 启用定时任务 */
@EnableScheduling
class Application {}

/* 固定频率任务 */
@Scheduled(fixedRate = 60000)  // 每 60 秒执行一次
public void syncData() {
    dataSyncService.sync();
}

/* Cron 表达式任务 */
@Scheduled(cron = "0 0 2 * * ?")  // 每天凌晨 2 点
public void generateReport() {
    reportService.generate();
}

二、分布式定时任务

多实例部署时,需要防止任务重复执行:

  • 分布式锁:只有获取锁的节点执行任务
  • 任务分片:按 ID 范围分配给不同节点
  • 调度中心:使用 XXL-JOB 等调度平台

使用 Redis 分布式锁

/* 分布式定时任务 */
@Scheduled(cron = "0 0/5 * * * ?")
public void handleTimeoutOrders() {
    String lockKey = "lock:task:timeout-orders";
    String lockValue = UUID.randomUUID().toString();

    Boolean acquired = redisTemplate.opsForValue()
        .setIfAbsent(lockKey, lockValue, Duration.ofMinutes(5));

    if (Boolean.TRUE.equals(acquired)) {
        try {
            orderService.handleTimeoutOrders();
        } finally {
            // 只有持有锁的实例才能释放
            if (lockValue.equals(redisTemplate.opsForValue().get(lockKey))) {
                redisTemplate.delete(lockKey);
            }
        }
    }
}

三、任务调度平台

推荐 XXL-JOB,国产开源,维护简单:

  • 可视化任务管理
  • 任务分片并行执行
  • 执行日志与失败重试
  • 任务报警通知

四、常见任务场景

  • 数据同步:每 5 分钟同步 ERP 数据
  • 超时处理:每分钟检查超时未支付订单
  • 报表生成:每天凌晨生成日报
  • 数据清理:每周清理 90 天前的日志
  • 库存预警:每小时检查库存低于阈值的商品
任务设计原则:
  • 幂等性:任务可重复执行不影响结果
  • 异常处理:捕获异常,记录日志,发送告警
  • 执行时间:避开业务高峰期,选择低峰时段
  • 监控告警:任务执行失败及时通知

五、总结

  • 简单任务用 Spring Task 即可
  • 分布式环境用 Redis 分布式锁防止重复
  • 复杂任务用 XXL-JOB 调度平台
  • 任务要保证幂等性,做好监控告警