513 words
3 minutes
如何设计高可用的分布式定时任务系统
定时任务是后端开发中的常见需求,如何设计高可用的分布式任务系统?
单机定时任务的问题
// ❌ 单机定时任务setInterval(async () => { await processOrders();}, 60000);
// 问题:// 1. 单点故障 - 机器宕机任务停止// 2. 重复执行 - 集群部署会执行多次// 3. 无法动态管理解决方案
1. 任务分片
-- 按 ID 取模分片SELECT * FROM ordersWHERE id % 10 = SHARD_IDAND status = 'pending';2. 分布式锁
// 使用 Redis 实现分布式锁async function acquireLock(key, ttl = 30) { const result = await redis.setnx(`lock:${key}`, Date.now()); return result === 1;}
async function releaseLock(key) { await redis.del(`lock:${key}`);}3. 延迟队列
interface DelayJob { id: string; topic: string; payload: any; delayTime: number; attempt: number;}
// 使用 Redis ZSet 实现延迟队列class DelayQueue { async push(job: DelayJob) { const score = Date.now() + job.delayTime; await redis.zadd('delay:queue', score, JSON.stringify(job)); }
async pop(timeout = 5): Promise<DelayJob | null> { const result = await redis.bzpopmin('delay:queue', timeout); return result ? JSON.parse(result[1]) : null; }}TIP推荐使用开源方案:XXL-JOB、ElasticJob、ScheduleJS
整体架构
┌─────────────────────────────────────────┐│ API │└─────────────────┬───────────────────────┘ │┌─────────────────▼───────────────────────┐│ 任务调度中心 ││ (分配任务、检查心跳、故障转移) │└─────────────────┬───────────────────────┘ │┌─────────────────▼───────────────────────┐│ 执行器集群 (Worker) ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │Worker 1 │ │Worker 2 │ │Worker 3 │ ││ └─────────┘ └─────────┘ └─────────┘ │└─────────────────┬───────────────────────┘ │┌─────────────────▼───────────────────────┐│ Redis / MySQL │└─────────────────────────────────────────┘核心特性
| 特性 | 说明 |
|---|---|
| 高可用 | 多 Worker 集群,故障自动转移 |
| 幂等性 | 任务执行结果可追溯,支持重试 |
| 动态管理 | 支持任务启停、修改参数 |
| 监控告警 | 执行时间、成功率、异常报警 |
| 日志追踪 | 任务执行日志完整记录 |
关键代码
@JobExecutor("orderProcessJob")public void execute(JobArgs args) { log.info("开始处理订单: {}", args.getJobId());
// 1. 检查任务是否已执行 if (!jobService.checkAndLock(args.getJobId())) { log.warn("任务已被其他节点执行"); return; }
// 2. 执行业务逻辑 orderService.process(args.getOrderId());
// 3. 更新任务状态 jobService.complete(args.getJobId());}总结
设计分布式任务系统需要考虑:
- 可靠性 - 任务不丢失、不重复
- 可用性 - 故障自动转移
- 可观测性 - 完整日志和监控
- 性能 - 支持大量任务并发执行