背景:用户在设定某一时刻触发某项任务,任务处理框架按照时间先后依次处理任务,即如果用户设置了9:30,9:31,9:32这3个时刻分别需要执行100个任务,那么任务系统在9:30时执行相应的任务,全部处理完之后再处理9:31的,也就是说9:31的任务是否执行不仅要看时间是否到点,还要看前面的任务是否完成。并且需要实现可扩展的架构,可以通过加机器来增加任务的处理能力。
框架设计:
1.任务的存储
这里为了快速整套架构是在redis的基础上实现的,也利用了一些redis的特性,不过一般分布式的缓存系统都应该提供了相应的功能。
内存中存储任务信息主要是两个方面
Key:任务id——taskId
Value:任务时间——taskDate
Key:根据当前距离1970多少天和设定的存储多少天数据的长度(这里假设打算存储30天的数据,那就是30)取模
HashKey:对应每天的秒数:secondInDay
HashValue: 对应的任务数据 taskInfo2.任务的分配
DistributeTaskService是一个java类,当类被加载的时候,通过ZK获取到锁的机器将启动RunDistributeTaskThread 线程,该线程从TASK_DATE_INDEX 取day指针和秒指针对应的数据,这里需要用缓存记录下任务运行的指针避免任务被停掉时丢失当前指针的位置。如果当前时间指针没有数据,那么sleep一下。如果有数据那么存储到redis
NS:TASK_STORE
key:TASK_KEY
value:任务数据列表
将记录放到redis的TASK_STORE,并删除掉已经分发的redis原来区TASK_DATE_INDEX的记录,然后指针往下移动一位
3.任务的执行
TaskService 被加载时调起RunTaskThread线程,从第二部的TASK_STORE中leftPop出记录并处理。这里可以用多机多线程来处理,因为leftPop是线程安全的