一种分布式定时任务调度系统及方法
技术领域
本发明涉及计算机和数据处理领域,具体涉及一种分布式定时任务调度系统及方法。
背景技术
目前普遍使用传统的MQ系统存储序列化后的任务,但是MQ系统本身的顺序性消费的特性无法保证消费者按照特定时间点消费消息,从逻辑上无法保证按时间触发的特性。而现有的Cron模式下的定时调度则存在一个很大的弊端,即只能指定某一任务在某个特定的时间周期内在特定的某一时间执行或者周期性执行,因此无法满足随时指定任意时间点触发。如果同一时刻大量的任务需要执行,如果任务积压严重,执行器就无法保证任务执行的时效性。
发明内容
针对现有技术的不足,本发明旨在提供一种分布式定时任务调度系统及方法,采用redis的有序集合redis zset作为存储介质,并且支持任务散列存储以及多执行器实例分布式调度,提供了对指定时间点调度执行特定任务的特性,从而从底层解决自定义任务指定任意时间点执行的实现。
为了实现上述目的,本发明采用如下技术方案:
一种分布式定时任务调度系统,包括:执行引擎、执行器、redis注册中心、rediszset分片和发送器;
所述执行引擎用于通过sdk根据任务散列算法将待执行任务散列后写入rediszset分片中;
所述redis zset分片用于缓存待执行任务;
所述执行器中部署有一个或以上的执行器实例,每个执行器实例均包含有一个轮询线程和执行线程,所述轮询线程用于从redis zset分片中获取执行时间小于当前系统时间的任务,交给执行线程执行;
发送器:用于执行过滤器过滤之后的任务,将对应的消息发送至相应的目标。
进一步地,redis zset分片的数量为可配置项,redis zset分片的数量写入redis注册中心,sdk在每一次执行引擎启动时都向redis注册中心订阅最新的redis zset分片的数量,据此更新自身的配置以及任务散列算法,以将加入的待执行任务均匀散列在各个redis zset分片中。
进一步地,所述执行器中还包括有过滤器,执行线程将任务交给过滤器,所述过滤器用于对任务进行频次过滤以及黑白名单过滤,并将经过过滤的任务交给发送器执行发送,将对应的消息发送给相应的目标。
更进一步地,所述频次过滤的规则为可配置项,使用redis注册中心的kv格式存储,在执行器完成任务之后更新对应任务的次数值。
进一步地,在本实施例中,所述执行器所部署的执行器实例的数量为可配置项,小于或等于redis zset分片的数量,执行器实例的数量写入redis注册中心。
进一步地,执行器以jar形式存在,作为一个独立的java进程启动或集成进任何java系统。
本发明还提供利用上述分布式定时任务调度系统进行分布式定时任务调度的方法,包括如下步骤:
S1、在服务端启动执行引擎,sdk根据任务散列算法将待执行任务散列后均匀写入各个redis zset分片中;
S2、各个执行器实例分别通过轮询线程轮询不同的redis zset分片,所述轮询线程获取执行时间小于当前系统时间的任务,交给所在执行器实例的执行线程执行;
S3、各个执行器实例的执行线程将任务交给发送器,发送器执行发送对应的消息给相应的目标。
进一步地,步骤S2中,所述轮询线程获取执行时间小于当前系统时间的任务的具体过程为:
执行器的轮询线程取得redis zset分片的第一个元素,并反序列化为java对象后,比较当前系统时间戳和该待执行任务的执行时间戳,如果当前时间戳>=待执行任务的执行时间戳,那么将该待执行任务交由执行线程,并删除该任务,否则继续轮询下一个redis zset分片。
进一步地,步骤S3中,各个执行器实例的执行线程先将待执行任务交给过滤器,所述过滤器对待执行任务进行频次过滤以及黑白名单过滤,并将经过过滤的任务交给发送器,发送器对待执行任务执行发送,将对应的消息发送至相应的目标。
进一步地,步骤S3中,所述发送器支持短信、邮件、推送的方式发送消息。
本发明的有益效果在于:
本发明采用redis的有序集合redis zset作为存储介质,并且支持任务散列存储以及多执行器实例分布式调度,提供了对指定时间点调度执行特定任务的特性,从而从底层解决自定义任务指定任意时间点执行的实现。
附图说明
图1为本发明系统的组成示意图;
图2为本发明方法中各个执行器实例轮询不同分片的示意图。
具体实施方式
以下将结合附图对本发明作进一步的描述,需要说明的是,本实施例以本技术方案为前提,给出了详细的实施方式和具体的操作过程,但本发明的保护范围并不限于本实施例。
以下先对本实施例中涉及到的专业术语作简单解释:
注册中心:有新的执行器实例启动时,协调多个执行器信息。
任务:一个需要推送的任务实例,包含执行时间、目标ID、模板ID、扩展信息等。
执行器:一个deepexe-core实例,负责拉取分片中的任务并按时执行。
sdk:jar包形式存在,需要调用执行引擎的应用通过sdk其将任务加入队列分片。
任务队列:按照执行时间排序的任务队列。
分片:redis中若干个zset结构。
任务散列:sdk添加任务时会根据任务的hash值将任务散列在特定分片中。
频次过滤器:避免对用户造成信息骚扰,系统设置了每天可以向用户推送信息的最高频次,不同的推送类型单独控制,彼此不受影响。暂时只实现了天粒度的频次控制。
黑白名单过滤器:有的用户明确不需要被推送信息,就可以设置黑名单禁止向此用户推送信息。有的需要指定只能向某些用户推送信息,其他用户都不能推送,就需要设置白名单进行过滤,在白名单内的用户才推送。
轮询线程:轮询分片头元素,符合条件将其remove并将元素交给执行线程。
执行线程:得到轮询线程传递的任务并完成解析,过滤,执行。
本实施例提供一种分布式定时任务调度系统,如图1所示,包括:执行引擎、执行器、redis注册中心、redis zset分片和发送器;
执行引擎用于通过sdk(jar包形式存在于业务项目内)根据任务散列算法将待执行任务散列后写入redis zset分片中;执行引擎可以为Java应用;
redis zset分片用于缓存待执行任务;
在本实施例中,redis zset分片的数量为可配置项(可以设置默认值,例如设置默认值为5),redis zset分片的数量写入redis注册中心,sdk在每一次执行引擎启动时都向redis注册中心订阅最新的redis zset分片的数量,以更新自身的配置以及任务散列算法,以将加入的待执行任务均匀散列在各个redis zset分片中。
所述执行器中部署有一个或以上的执行器实例,每个执行器实例均包含有一个轮询线程和执行线程,所述轮询线程用于从redis zset分片中获取执行时间小于当前系统时间的任务,交给执行线程执行;
在本实施例中,所述执行器中还包括有过滤器,执行线程将任务交给过滤器,所述过滤器用于对任务进行频次过滤以及黑白名单过滤,并将经过过滤的任务(可先作设定的格式化)交给发送器执行发送,将对应的消息发送给相应的目标。通过过滤器对任务进行过滤可以避免对发送目标造成不必要的打扰。
进一步地,所述频次过滤为可配置项,使用redis注册中心的kv格式存储,在执行器完成任务之后更新对应任务的次数值。
针对一个目标ID的频次记录格式可以为:
任务类型:目标ID:时间周期
如,发送给某个手机号某天的短信数量key为:
sms:138xxxxxxxx:day
value=为当天已经发送的短信数量,并且该Key会在当天23:59:59自动失效,避免redis垃圾数据的堆积。
同理,当前周和当前月的格式为
push:138xxxxxxxx:week
该值会在本周最后一天23:59:59失效
email:xxx@xx.com:month
该值会在当月最后一天23:59:59失效
在本实施例中,所述执行器所部署的执行器实例的数量为可配置项,小于或等于redis zset分片的数量,执行器实例的数量写入redis注册中心。如此可以避免争抢同一redis zset分片的头结点,在保证分布式一致性的同时提高性能。如果执行器实例数超过redis zset分片的数量,那么某些redis zset分片一定会有超过一个的轮询线程争抢头结点,造成不必要的性能损失。
在本实施例中,执行器以jar形式存在,可以作为一个独立的java进程启动,也可以集成进任何java系统。
发送器:用于执行过滤器过滤之后的任务,将对应的消息发送至相应的目标。
利用上述分布式定时任务调度系统进行分布式定时任务调度的方法,包括如下步骤:
S1、在服务端启动执行引擎,sdk根据任务散列算法将待执行任务散列后均匀写入各个redis zset分片中;
S2、各个执行器实例分别通过轮询线程轮询不同的redis zset分片,所述轮询线程获取执行时间小于当前系统时间的任务,交给所在执行器实例的执行线程执行;
S3、各个执行器实例的执行线程将任务交给发送器,发送器执行发送对应的消息给相应的目标。
上述方法中,步骤S1中,redis zset分片的数量为可配置项,redis zset分片的数量在设置之后会写入redis注册中心,所述执行引擎的sdk在每一次执行引擎启动时都向redis注册中心订阅redis zset分片的数量的最新配置,据此更新自身的配置以及任务散列算法,以将加入的待执行任务均匀散列在各个redis zset分片中。
进一步地,上述方法的步骤S2中,所述轮询线程获取执行时间小于当前系统时间的任务的具体过程为:
执行器的轮询线程取得redis zset分片的第一个元素,并反序列化为java对象后,比较当前系统时间戳和该待执行任务的执行时间戳,如果当前时间戳>=待执行任务的执行时间戳,那么将该待执行任务交由执行线程,并删除该任务,否则继续轮询下一个redis zset分片。
进一步地,上述方法的步骤S3中,各个执行器实例的执行线程先将待执行任务交给过滤器,所述过滤器对待执行任务进行频次过滤以及黑白名单过滤,并将经过过滤的任务交给发送器,发送器对待执行任务执行发送,将对应的消息发送至相应的目标。
进一步地,上述方法的步骤S3中,所述发送器支持短信、邮件、推送的方式发送消息。
对于本领域的技术人员来说,可以根据以上的技术方案和构思,给出各种相应的改变和变形,而所有的这些改变和变形,都应该包括在本发明权利要求的保护范围之内。