集群模式下Vert.x定时器如何实现故障自动迁移?
Vert.x Hazelcast集群下宕机定时器迁移方案
首先明确:Vert.x 原生的vertx.timer(包括setTimer一次性定时器、setPeriodic周期性定时器)是节点本地特性,本身没有集群高可用能力,节点宕机后本地定时器会直接丢失,要实现故障自动迁移需要基于Hazelcast分布式能力做额外的逻辑封装,具体实现步骤如下:
1. 定时任务元数据持久化
- 所有定时器的核心信息(任务唯一ID、原定延迟/周期、任务参数、上次执行时间、下次执行时间戳、执行状态)全部存储到Hazelcast的分布式
IMap中 - 配置该分布式Map的备份数≥2,保证单节点宕机时任务元数据不会丢失
2. 分布式锁保证任务唯一执行
- 每个集群中的Vert.x实例,启动一个固定间隔的本地扫描任务(比如间隔1秒,可根据精度要求调整),从分布式
IMap中筛选出「已到达下次执行时间、且当前无节点持有执行锁」的任务 - 筛选到待执行任务后,先尝试获取该任务对应的Hazelcast分布式锁
ILock,只有抢锁成功的节点可以执行该任务- 一次性定时器:执行完成后直接从分布式
IMap中删除对应任务元数据即可 - 周期性定时器:执行完成后更新
IMap中该任务的「下次执行时间戳」,再释放分布式锁
- 一次性定时器:执行完成后直接从分布式
3. 宕机自动接管逻辑
- 持有任务锁的节点意外宕机后,Hazelcast集群会自动检测到节点离线,自动释放该节点持有的所有分布式锁,同时分布式
IMap里的任务元数据因为有多副本备份不会丢失 - 其他存活节点的下一轮扫描会自动检测到该任务已到执行时间且无锁持有,自动完成抢锁、执行逻辑,无需人工干预
4. 精度优化方案(可选)
如果对定时器延迟精度要求很高,可以不用依赖全量扫描触发:节点抢到新的待执行任务后,先在本地创建一个对应时间的临时定时器,到点后再走抢锁执行逻辑;节点宕机后其他节点的全量扫描会做兜底触发,同时要注意本地临时定时器仅做触发用,实际执行权限完全由分布式锁和元数据状态决定,避免出现重复执行问题。
内容的提问来源于stack exchange,提问作者Kyon Xu
相关产品推荐
相关产品推荐

