网络文章

Java通过redis管理你的集群定时任务

前言早在实习的时候,笔者就接触了spring-task和quartz框架,相信任何java程序员都会有定时任务的需求,在单机上使用定时任务是非常简单的,但是在集群环境中就显得比较棘手:如何限定只有一台机器在执行定时任务某台服务宕机以后如何进行故障转移如何确定正在执行的是哪一台服务此问题官方肯定有解决方案,资料也不少:quartz集群分布式(并发)部署解决方案-Spring不过笔者是个比较懒的人,上

前言

早在实习的时候,笔者就接触了spring-task和quartz框架,相信任何java程序员都会有定时任务的需求,在单机上使用定时任务是非常简单的,但是在集群环境中就显得比较棘手:

  • 如何限定只有一台机器在执行定时任务

  • 某台服务宕机以后如何进行故障转移

  • 如何确定正在执行的是哪一台服务

此问题官方肯定有解决方案,资料也不少:quartz集群分布式(并发)部署解决方案-Spring
不过笔者是个比较懒的人,上述的解决方案需要配置不少的quartz表,并且业务里不需要动态配置定时任务,对quartz框架并无依赖,所以就考虑使用其他方式来实现定时任务的分布式调度。

初尝试Uncode-Schedule

Uncode-Schedule 是笔者在开源中国中看到的一个开源的分布式调度任务组件,与spring集成比较容易,使用方便,借助了zookeeper。在此我不多做评价,毕竟是个人的一个开源框架,使用过程中还是踩了一些坑,并且文档尚未齐全,用了一段时间后决定弃用了。有兴趣的同学可以了解下:分布式任务调度组件 Uncode-Schedule
所幸在填坑过程中对这个任务调度的过程有了一定了解,于是决定自己实现一个简单的任务调度器。

通过redis实现任务调度思路

实现功能之前,回顾下之前遇到的三个问题:单点执行,故障转移,服务状态。结合着redis的一些接口特性,解决思路如下:

  1. 使用redis作为任务调度中心,采用了redis的自动过期与分布式锁特性

  2. 每个服务的ip加项目名作为每台服务的唯一别名

  3. 通过redis中对应key值中的value来判定执行的是哪台服务: 如redis中key为  schedular_root:projectA, value为192.168.1.187. 意为项目projectA当前执行任务的节点为192.168.1.187这台机器上的服务

  4. 每次执行任务之前判定下redis中schedular_root:projectA是否为空,如果为空,则设置当前ip进去,设置一定时间的有效期,并执行定时任务;如果不为空,判断是否与

原创不易,完成人机校验,阅读全文

相关推荐