2023年初,我接手了一个遗留的库存同步系统。每天凌晨2点,系统通过ScheduledExecutorService执行一个定时任务,从ERP拉取数据更新到MongoDB。起初一切正常,但随着业务增长,问题开始暴露:任务偶尔不执行、偶尔重复执行、甚至出现数据不一致。这让我开始了为期三个月的调度系统重构之旅。
一、单机时代的痛:ScheduledExecutorService的局限
原有代码很简单:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); executor.scheduleAtFixedRate(() -> syncInventory(), 0, 1, TimeUnit.HOURS);单机部署,一旦服务器宕机,任务就丢了。更糟的是,当任务执行时间超过间隔时,会出现任务堆积。一次网络超时导致同步线程阻塞,后续任务排队等待,最终OOM。团队临时增加了重试和超时机制,但治标不治本。
二、引入Quartz:分布式调度的第一站
我们决定引入Quartz,利用其集群模式解决单点问题。Quartz使用数据库作为分布式锁,通过行锁(如MySQL的SELECT FOR UPDATE)保证任务只在一个节点上执行。
配置了集群后,部署了两台服务器。测试阶段一切顺利,但上线一周后,发现任务偶尔重复执行。排查日志发现,当某节点GC停顿超过数据库锁超时时间(默认30秒),Quartz会认为该节点失联,触发其他节点抢占锁,导致两个节点同时执行任务。
核心洞见:Quartz的分布式锁依赖数据库行锁,在高并发或GC场景下容易出现锁失效。而且任务执行频率越高,锁竞争越激烈,数据库压力越大。
我们尝试调优Quartz参数:
- 增大锁超时时间(org.quartz.jobStore.acquireTriggersWithinLock)到60秒
- 减少调度线程池大小
但效果有限。而且Quartz的集群模式不支持动态扩缩容,每次加机器都要手动更新配置文件。
三、自研调度中间件:基于Redis和Raft的实践
经过调研,我们决定自研轻量级调度中间件,核心思想是:
- 使用Redis作为分布式锁(Redlock算法)代替数据库锁,减少锁超时问题
- 引入Leader选举(基于Raft协议),由Leader统一分配任务,避免竞争
- 支持动态注册和发现,节点上下线自动感知
架构设计如下:
// 简化版Leader选举核心逻辑 public class LeaderElection { private final String lockKey = "scheduler:leader"; private final long ttl = 10000; // 10秒 private volatile boolean isLeader = false; public void elect() { String instanceId = UUID.randomUUID().toString(); while (true) { boolean locked = redis.setIfAbsent(lockKey, instanceId, ttl, TimeUnit.MILLISECONDS); if (locked) { isLeader = true; // 定期续约 startRenewTask(); break; } // 等待并重试 Thread.sleep(1000); } } private void startRenewTask() { scheduledExecutor.scheduleAtFixedRate(() -> { redis.expire(lockKey, ttl, TimeUnit.MILLISECONDS); }, ttl/2, ttl/2, TimeUnit.MILLISECONDS); } }Leader节点负责从数据库加载任务列表,并分配给各个Worker节点。Worker节点执行完任务后上报状态,Leader更新任务记录。如果Worker节点宕机,Leader会在超时后重新分配任务。
四、效果数据与经验总结重构后,系统稳定运行6个月,未出现任务重复执行或丢失的情况。性能对比:
- 任务调度延迟:平均从500ms降至20ms
- 数据库压力:QPS从200降至20(锁操作从数据库转移到Redis)
- 运维成本:支持动态扩缩容,无需重启服务
经验总结:
- 分布式调度核心是“选主+分片”,避免锁竞争
- Redis锁比数据库锁更适合高频率任务,但要注意Redis自身高可用
- 不要过度设计:如果任务量不大,Quartz+数据库足够;但若需要高可靠、低延迟,自研更可控
这次重构让我深刻体会到:技术选型没有银弹,只有最合适的。如果你的业务也遇到类似痛点,欢迎交流。我们铭锦数智在分布式系统设计上有不少实战经验,也提供相关技术咨询和定制服务。