使用Chronos执行whenever任务

  • 时间:
  • 浏览:1

不同于crontab默认经常从零时零分刚始于了了计算下次执行时间,chronos的schedule格式时我不让本人指定起始时间。

这名解析器和whenever三种的功能类似,whenever将schedule.rb转换为crontab格式,让让我们让我们 的解析器则将其转化为chronos支持的格式。

这名基准时间的计算还是稍稍这名麻烦的:

有了基准时间,再根据间隔时间就可不可否 计算出下一次的执行时间了。

随便说说代码逻辑很简单,但依然有几点是时要注意。

对于业务上时要定时执行的后台任务,让让我们让我们 使用ruby的whenever模块定义执行时间及其对应的rake任务,因此将所有任务放在三个 多 长期运行的docker容器,由中间的crond服务执行配置的cron任务。

以斜杠分隔的第二每种即为刚始于了了执行时间,第三每种为执行间隔时间,下一次应该哪几个如果执行都有从第二每种指定的时间刚始于了了计算的。为了保证每一次的执行时间都符合预期,这里时要三个 多 绝对时间作为刚始于了了执行时间。但又非要简单地设为过去某个时间点,愿因和chronos那我规则有关:当三个 多 任务部署后,chronos会判断其刚始于了了执行时间,不可能 大于当前时间则等到了刚始于了了时间再执行任务,小于搞笑的话则立即执行一次任务。也而是说,不可能 刚始于了了时间为过去时间,这么任务每次被部署后不会 被执行一次。

拆分成多个chronos任务后,每个任务以短系统线程池池的土办法运行,执行完毕即退出,释放相应资源,因此还能对不同的任务配置不同的配额,大大提高了资源利用率。此外,这次迁移还带来了这名额外的改进。

whenever中,三种关注任务的名称。但在chronos中,每个rake都被拆分成了独立的任务,所以就时要三个 多 名字来标识每三个 多 任务。让让我们让我们 使用rake土办法的参数——rake task name——作为任务名,当然,时要正确处理特殊字符以及重名的情況。

通过chronos的Web UI,可不可否 查看所有任务的上次执行情況,以及下次执行时间,在Mesos Web UI上也可不可否 查看每个失败任务的错误日志。以往的运行模式非要登陆到容器中查看cron的日志不能知道任务执行的具体情況。

在让让我们让我们 将容器调度框架迁移到mesos+marathon如果,所有容器都时要设置资源配额。执行后台任务的容器闲置时白白占用了配额,因此配额的设置也非要以所有任务中最重的三个 多 为准,所以这名土办法造成了较大的资源浪费。

另外,受crontab的限制,whenever无法表示every(45.days)那我的时间,愿因是crontab中日期字段不出0-31之间搞笑的话(0 0 */45 * *),最终的执行效果是每天执行一次。不可能 非要用crontab表示每4多日执行一次,应该是那我的:

为了叙述上的简单,这里假设chronos上的所有任务都有由三个 多 schedule.rb创建的。实际上让让我们让我们 的chronos上运行着多种类型的任务,让让我们让我们 使用三个 多 前缀作为命名空间来区分不类似型的任务。

针对这名疑问,让让我们让我们 将所有whenever任务拆分为短系统线程池池运行在chronos上,每个任务单独配置资源,因此执行完毕立即退出,资源不让闲置。

这里正确的做法大致是:在代码中设置三个 多 过去时间作为基准时间,部署时根据基准时间和间隔时间计算出下次的执行时间。

好在这并都有三个 多 疑问,不可能 whenever也是那我正确处理的。whenever会将时间解析为尽不可能 大的单位,因此25950表示三个 多 月而都有50天。让让我们让我们 在实现上沿用这名逻辑。

不可能 schedule.rb是ruby代码,所以使用ruby来实现解析器自然也最为方便。只时要实现对应的every()土办法以及rake()土办法,在every()rake()土办法中将解析到的执行时间和执行搞笑的话存入实例变量@schedules中即可。

mesos是三个 多 分布式调度框架,chronos任务会被mesos分配到至少的节点上执行。配合重试机制,当任务因某三个 多 节点故障而执行失败后,chronos会在这名节点重新执行该任务。

至少是这么必要为这名小众需求实现繁复的逻辑,whenever会将4多日繁复为三个 多 月。在chronos中则这么这名疑问,可不可否 放心地使用那我的时间。

尽管要改造whenever任务,但让让我们让我们 三种打算离开whenever转而在业务层直接定义chronos支持的ISO 8501时间格式 。一是whenever三种提供的DSL语法非常简单直观,对Ruby开发者更加友好;二是服务的运行环境对于业务层来说应该是透明的。让让我们让我们 的做法是增加三个 多 解析模块,在部署的如果将whenever的schedule.rb转换为多个chronos任务。

任务被放在chronos,其类型和marathon上的服务一样,都属于mesos任务。那我就统一了自动化监控的逻辑,只时要监控所有mesos任务即可,不让为不类似型的任务编写不同的监控逻辑。

让让我们让我们 将形如10.minutes1.day以及1.month的时间表示定义为Fixnum的对应土办法,最终其会被转换为秒数,这在rails中相当常见。在every()土办法内拿到的间隔时间而是转换如果的秒数,因此对于25950这名数,它究竟是表示50.days天还是1.month呢?

让让我们让我们 将schedule.rb中定义的所有任务拆分因此部署到chronos,不可能 schedule.rb中某个任务被删除不可能 改名了,这么旧的任务还保留在chronos中。对于这名情況的正确处理,让让我们让我们 在部署的如果记录下本次部署的所有任务名,部署完成后遍历chronos上的所有任务,所有不出本次部署中的任务则是时要删除的。

crontab这么重试机制,不可能 想失败后重新执行,时要在每个业务代码中实现相应的逻辑。作为三个 多 定所处Fault Tolerant的任务调度框架,chronos当然是默认支持重试的。不可能 任务执行失败,chronos会尝试重新执行,直到成功不可能 达到最大重试次数。