任务调度中心

来源:互联网 发布:淘宝商品类目 编辑:程序博客网 时间:2024/05/21 12:24

调度中心的意义

在电商系统中链路很长、业务逻辑复杂,会存在成百上千的后台定时任务执行。比如凌晨
两个系统对账,归档历史订单等任务。在最初系统中,各个任务都是开发使用Quartz或者
自己使用java线程池进行调度。随着业务的复杂,大量的后台任务越来越难以管理和维护:

  • 缺少一个集中的管理方式,可视化跟踪任务的执行情况,不能经常动态的修改任务
  • 当任务执行失败或者超时时,没有统一的监控报警机制
  • 当出现问题时,能简单的定位问题,知晓任务的历史执行轨迹
  • 大部分任务只能有一个实例运行,故都存在单点问题
  • 一般简单的使用Quartz或者java线程池,当应用多个实例部署时,很难做到分布式

基于以上原因,促使闪电购开发了一套自己的任务调度中心。满足以下需求:

  • 一个简单集中式的管理后台,只需简单操作即可进行任务管理
  • 详细记录任务的执行细节,如执行时间,执行状态,出错原因等
  • 任务监控报警机制,当任务执行失败或者超时,短信邮件报警
  • 调度可靠性保证,每个任务没有执行完成后,不会进行下个时段的执行
  • 在多个任务实例中,一个任务在一个执行时段只会一个实例执行

调度中心的设计原理

名词解释:

  • 任务管理中心(manager server):负责提供可视化的任务的添加,删除,开启关闭,
    查询任务执行情况等操作
  • 任务调度中心(scheduler server):负责任务的执行调度,随即选择对应任务实例
    进行执行任务
  • 监控中心(monitor server):负责维持任务执行实例与服务器之间的心跳机制,
    以及任务超时或者失败报警通知
  • 任务执行实例(job execute instance):执行任务应用的部署实例
  • 消息中间件(notify server):负责消息可靠的转发,闪电购开发的消息中间件,后
    面详细讨论notify server的实现原理

闪电购技术环境

由于闪电购后台服务大部分基于java开发,采用开源的spring框架,使用阿里巴巴的开源
dubbo进行远程调用,故任务调度中心结合spring特性,设计分布式系统。

设计难点(中心化与非中心化)

由于需要充分保证调度的可靠性,首先想到的是去中心化方案,集群中每个节点每个节点
都可以进度调度,通过协调保证每个任务只有单实例运行。但是这种实现方式虽然看起来
很好,但实现还是非常复杂,定位问题也很困难。最后权衡下来,采用中心化方案,但是
通过Zookeeper的选举机制,当master调度节点出问题后,可以快速的failover到其他slaver
调度节点。

总体设计

jobcenterDisignPic

  1. 任务A通过任务管理中心添加完成后,由任务中心将任务存储在mysql数据库中,然后通
    过dubbo接口将任务通知任务调度中心;
  2. 任务调度中心将任务A添加进入调度队列中。当到达任务A执行时间后,调度中心首先在
    mysql数据库中添加一个任务执行记录,其状态为等待执行,然后向消息中间件发送消息,
    消息投递的group为任务A执行的应用名称;
  3. 这样在任务A的所有实例中,将有一个机器接到消息,接到消息后,首先通过dubbo同步
    更新将执行记录的状态由待执行更新为执行中(如已经为执行中时,则dubbo同步更新失败,
    通过该策略,保证了只有一个任务实例执行任务),如果修改成功后则开始执行任务,执行
    完成或者出错,则同步调用通知监控中心任务执行的结果,并发送消息给监控中心通知任务
    执行结果。通过同步调用,异步补偿机制保证执行结果一定能通知到监控中心。
  4. 监控中心接受到任务A执行结果后,写入数据库保存,需要保证幂等性。
  5. 其中每个任务实例在应用初始化时,与监控中心维持心跳机制,让监控中心知道每个实
    例的存活状态,当任务在执行中时,而机器挂掉,则根据任务配置的属性,是继续让下一个
    执行实例重新执行还是报警告知任务拥有者。

一个任务的执行时序图如下:
jobcenterTimePic

优化改进点

由于任务调度中心采用中心化方式,所有的任务的调度都在一个单节点上,当某一天任务量
足够大,难以承载时,到这个时候我们计划中心节点不再进行任务调度,只进行任务分发。
就像发扑克牌一样,这个周期内这个任务发给这个节点了就一直由这个节点进行调度。

欢迎大家随时讨论,QQ5303-121-192

1 0
原创粉丝点击