Rails Sidekiq 定时任务的尝试

lithium4010 · 2017年01月17日 · 最后由 easonlovewan 回复于 2017年01月18日 · 4523 次阅读

补充一下 crontab 是我之前用的方式,另外有同事正在使用 sidekiq_cron

我觉得这两种方式都有痛点:

crontab

  • 和 docker 的结合不好做
  • 每次起任务都是新的进程,如果结合 rake 的话不注意会需要不少临时内存

sidekiq_cron

  • 相当于 monkey-patch 了 Sidekiq

两者都需要注意任务重复触发的问题。

利用 sidekiq 自带的 perform_in & perform_at 实现 schedule 的问题目前我看来就是实现起来不如前面二者简便,不能直观看出系统中有哪些计划任务


尝试利用 sidekiq 自身的 perform_in 来实现每分钟定时任务

大家是否试过这种做法,有什么样的坑?

首先这个每分钟任务是可以接受初始化的时候多执行几次的,但是应该随时间快速收敛到只有一个。

这个方案的好处是不管部署了多少个实例,跨了多少个服务器,任务计划总是一份。

# initializers/schedule_seeds.rb

SchedulePerMinuteWorker.perform_async
require 'sidekiq/api'

class SchedulePerMinuteWorker
  include Sidekiq::Worker

  def perform
    # 清除重复的任务计划
    Sidekiq::ScheduledSet.new.select {|job| job.klass == self.class.name }.each(&:delete)

    run_schedule_works

    # 结束时将自己推入
    SchedulePerMinuteWorker.perform_in(1.minute)
  end

  # 每分钟执行的任务
  def run_schedule_works
    # TODO 业务逻辑
  end
end

我发现大部分的定时任务都不需要特别精确,能否举例一些业务场景需要用到精确的定时任务?

付费版本有定时任务功能

#1 楼 @kikyous 没有购买付费版,希望能讨论一下这种做法

不推荐这么做,还是用应该更合适的工具做适合的事情。推荐的做法是用定时任务(crontab、rufus-scheduler、crono)来做一个调度器,具体的事情还是有 Job 系统来完成

#3 楼 @zamia 你试过这么做吗?或者有更具体一点的理由?我目前是用 crontab 的,但是这个东西需要 linux 上有,而且不方便和 docker 结合使用。

#4 楼 @lithium4010 我们现在系统就是这么做的,回头写篇文章解释一下。主要好处就是可以利用 Job 本身的重试机制、错误处理机制,而 Cron 本身很简洁,只是一个触发器。

#5 楼 @zamia 你说的这么做是指 crontab?

#5 楼 @zamia 我是指利用 perform_in

#6 楼 @lithium4010 哦,我们并没有使用 perform_in,我们使用 crono + Job

#5 楼 @zamia crontab 我没办法分布式。crontab 的麻烦在于我需要指定一台机器有这个 crontab, 而不能面向一个应用

#8 楼 @zamia 后面这些方案都要用到额外的进程和资源,也需要额外维护。而 perform_in 只需要 sidekiq

#11 楼 @lithium4010 还是看具体的使用场景

sidekiq-scheduler 替换 crontab 已经一年多了,很稳定。避免任务重叠可以自己加锁。

#13 楼 @gihnius 这个看起来很不错

用过 corntab 也用过 rufus-scheduler 一直很稳定啊

lithium4010 Rails 最佳实践 - 定时任务 提及了此话题。 01月19日 09:11
需要 登录 后方可回复, 如果你还没有账号请 注册新账号