Grape-DelayJobSystem 正在参加 2021 年度 OSC 中国开源项目评选,请投票支持!
Grape-DelayJobSystem 在 2021 年度 OSC 中国开源项目评选 中已获得 {{ projectVoteCount }} 票,请投票支持!
2021 年度 OSC 中国开源项目评选 正在火热进行中,快来投票支持你喜欢的开源项目!
2021 年度 OSC 中国开源项目评选 >>> 中场回顾
Grape-DelayJobSystem 获得 2021 年度 OSC 中国开源项目评选「最佳人气项目」 !
授权协议 Apache
开发语言 Java JavaScript HTML/CSS
操作系统 跨平台
软件类型 开源软件
开源组织
地区 国产
投 递 者 dinstone
适用人群 未知
收录时间 2024-02-04

软件简介

Grape是基于Redis实现的一个高并发、高性能、高可用的分布式延迟任务系统。主要提供以下特性:

  1. 任务具备延时、过期重试、重试次数、预留时间等功能。
  2. 通过Vert.x异步IO提供高性能 HTTP Restful API。
  3. 任务调度支持毫秒级精度,0毫秒延迟,Redis损耗小。
  4. 具备横向扩展能力,丰富的业务和性能指标监控接口。

什么是延迟任务

想必大家都在网上购过物,比如,你在淘宝上买了件商品,收到货物后,即使你不主动去点 “确认收货”,经过若干天后,系统会自动确认收货,完结订单。

这是怎么做到的呢?其实,这个背后隐藏着一个常用技术,就是延迟任务。顾明思议,我们把需要延迟执行的任务叫做延迟任务。

请注意,延迟任务不是定时任务,它们之间是有显著的区别:

  1. 定时任务有明确的触发时间,延迟任务没有。
  2. 定时任务有执行周期,而延迟任务在某事件触发后一段时间内执行,没有执行周期。
  3. 定时任务一般执行的是批处理操作的任务,而延迟任务一般是针对单个处理操作的任务。

延迟任务典型场景

使用延迟任务的典型场景有以下这些:

  1. 红包 24 小时未被查收,需要执行退款业务。
  2. 提交订单 30 分钟后,用户如果没有付钱,系统需要自动取消订单,归还库存。
  3. 直播时间快到了,需要给关注的用户发送消息,提醒上线。
  4. 支付完成后,需要异步回调通知业务系统的支付完成状态,在至少一次的QoS要求下,需要按指数幂退时间间隔延迟执行回调。

仔细审查这些业务场景,会发现每个业务处理都是在一定时间后执行特定的任务,而触发的时间不是固定的,如果做成定时任务来处理会很麻烦,而且时效和性能无法很好的保证。因此,创建一个解决此类问题的延迟任务系统才是最佳实践。

延迟任务系统的特性

  1. 延迟任务的生产和消费需要支持高并发、高性能、高可用。延迟任务的提交通常参与到核心的业务流程中,如果不能保证并发和性能,将对核心业务有影响。
  2. 延迟任务的生产需要支持重复提交,很多场景下可能会存在重试的情况。
  3. 延迟任务的消费需要支持可靠消费,也就是说要需要明确的知道是否成功执行了任务。通常,这需要系统在消费时暂存延迟任务信息,在执行成功后提交反馈。
  4. 延迟任务具备延时、自动重试、优先级等功能。
  5. 延迟任务系统需要具备横向扩展能力,丰富的业务和性能指标监控能力。

Grape的核心概念

  • Job :业务定义的延迟任务,有以下属性:

    • id,任务ID,由业务系统指定,全局唯一。
    • dtr (delay to run),任务延时运行时间,单位是毫秒。
    • ttr (time to run),任务预期执行时间,单位是毫秒。超过 ttr 则触发任务重试。
    • noe (number of executions),任务执行次数,默认从0开始,消费一次自增一。业务系统可以根据该属性做业务处理,如指数幂退调用等。
    • data (job content),任务内容,字节数组。业务系统可以提交一些任务执行需要的参数,避免再次查询数据库准备数据。
  • Tube :同一个主题的延迟任务队列,用于区分和管理不同业务分组的延迟任务。

  • Broker :延迟队列代理,用于管理Tube集合的运行。

  • Server :Grape服务实例,为指定 namespace 的Broker提供 Restfull 的 Job API、Tube API、管理API和管理UI。

整体架构设计


Grape 是一个无状态的HTTP服务,很容易横向扩展。业务系统可以通过7层负载均衡器访问Grape-Server集群。

  • Grape-Server主要由API处理器和Broker组件构成。

  • Broker内部由Scheduler和Tube组件构成。
    • Scheduler负责发现和加载Tube实例,以便更多的Broker实例分担Tube实例的管理压力,同时对外提供API服务。
    • Tube组件是延迟任务的管理器,其内部维护了3个Sorted Set队列:Deleay Queue、Remain Queue、Failed Queue。根据延迟任务的生命状态机制,任务在各个队列之间流动。
  • Redis存储主要包含了三类数据,分别是tube的名称集合、tube的队列模型和延迟任务模型。
    • tube的名称集合,是一个Set类的集合,代表当前由多少可用的延迟队列。
    • tube的队列模型,3个队列都是Sorted Set数据结构,Key是tube名称,数据是以延迟时间排序的任务ID。
    • 延迟任务模型,每个任务是一个HashMap结构的数据,Key是任务ID,Value是任务的各个属性。

任务生命周期

Grape借鉴了Beanstalkd的任务管理机制,因此在Grape中,延迟任务可能处于四种状态之一:“delay”、“ready”、“remain”或“failed”。围绕任务状态的迁移动作,满足了很多通用场景对延迟任务的诉求。

Status

  • delay 状态,业务系统生成(produce)延迟任务后进入该状态。处于该状态的任务可以被删除(delete)。当前时刻大于任务延时后,任务迁移至ready状态。

  • ready 状态,业务系统生成(produce)延时为0毫秒的延迟任务进入该状态,或已过了延时的延迟任务进入该状态。进入该状态的任务可以被消费。消费任务(consume)将进入remain状态。

  • remain 状态,任务在消费期间会出现4种情况:

    1. 任务执行时间操过了ttr,或者执行任务的线程跑飞、业务进程宕机等异常情况下,任务会被调度到ready状态,使得任务可以被再次消费。
    2. 任务执行很顺利,但还没有拿到期望的结果,希望能再次重试,那么可以指定延时并释放(release)任务至delay状态。
    3. 任务执行很顺利,拿到了期望的结果,那么可以结束(finish)任务。
    4. 任务执行失败了,暂时无法处理,可能需要人工介入,可以先雪藏(bury)起来,则任务迁移至failed状态。
  • failed 状态,该状态的任务通常为异常任务,可通过查看(peek)任务来决策,如果需要继续执行,则打回(kick)到delay状态,如果不在需要执行,则可丢弃(discard)掉任务。

展开阅读全文

代码

的 Gitee 指数为
超过 的项目

评论

点击引领话题📣 发布并加入讨论🔥
暂无内容
发表了博客
{{o.pubDate | formatDate}}

{{formatAllHtml(o.title)}}

{{parseInt(o.replyCount) | bigNumberTransform}}
{{parseInt(o.viewCount) | bigNumberTransform}}
没有更多内容
暂无内容
发表了问答
{{o.pubDate | formatDate}}

{{formatAllHtml(o.title)}}

{{parseInt(o.replyCount) | bigNumberTransform}}
{{parseInt(o.viewCount) | bigNumberTransform}}
没有更多内容
暂无内容
暂无内容
0 评论
5 收藏
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部