quartz在双机热备场景定时任务双份执行冲突解决方案
quartz在双机热备场景定时任务双份执行冲突解决方案
quartz在双机热备场景定时任务双份执行冲突解决方案
场景和挑战
对于单体架构,使用Quartz
框架做定时任务管理,默认单实例运行。在双机热备场景,容易出现定时任务分别在主、备节点同时运行、跑双份的冲突问题。
基于分布式锁的定时任务管理(不推荐)
利用redis、数据库等中间件 1) 主节点运行时,向中间件写入key,创建锁; 2) 备节点quartz的运行时,检测到锁的存在,不执行定时任务。
方案优缺点:双机热备场景容易出现中间件主备数据同步延迟、失效、网络不通等问题,导致锁失效。
基于全局启停控制配置参数的定时任务管理(不推荐)
quartz提供了spring.quartz.auto-startup
配置参数来控制当应用启动时是否自动启动定时任务。默认true
该参数只在应用启动时生效,后续即使使用热更新方式修改参数值,但任务启停效果无效。
方案优缺点:每次主备切换后,都需要重启实例,重启过程中会导致应用不可用。
基于自定义开关参数热更新的定时任务管理
1)配置文件增加自定义开关参数,值true或false
2)在任务调度前,增加代码逻辑,判定自定义开关参数值,false则跳过任务执行
3)在keepalived
配置notify通知脚本,监听到主备状态切换,调用脚本修改配置文件的开关参数,触发配置文件热更新,实现任务冲突控制。
方案优缺点:虽然要对原应用做编码改造,但无需重启应用,保证应用提供的服务持续可用。
本文由作者按照 CC BY 4.0 进行授权