Rails Sidekiq 定时任务的尝试

lithium4010 · 发布于 2017年1月17日 · 最后由 easonlovewan 回复于 2017年1月18日 · 578 次阅读
8744

补充一下 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

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

共收到 15 条回复
2564

付费版本有定时任务功能

8744

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

3214

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

8744

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

3214

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

8744

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

8744

#5楼 @zamia 我是指利用perform_in

3214

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

8744

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

8744

#8楼 @zamia 我去看看crono

8744

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

3214

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

6061

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

3214

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

17671

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

8744 lithium4010 Rails 最佳实践 - 定时任务 中提及了此贴 1月19日 09:11
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册