您的当前位置:首页正文

Sidekiq 和 ActiveJob 实现定时循环任务

来源:华佗小知识

Scheduler / Cron for Sidekiq jobs

Sidekiq-crom 简介

这个 Gem 是 Sidekiq 实现定时任务的一个插件,Sidekiq-Cron 的命名让人一开始觉得它实现原理是基于 Linux 的 Cron ,其实不然。下面列出几点需要注意事项。

  • 优点
    • 简单易用
    • 它有一个 Web 页面,能够直接嵌入 sidekiq-web 管理页面中
    • 使用 YAML 配置定时任务
    • 可与 ActiveJob 结合使用,当然也可单独使用 Sidekiq Worker
  • 缺点
    • 不兼容 forking processes 的类 Unicorn web 容器

Sidekiq-cron 使用

  • 添加到 Gemfile 中 gem "sidekiq-cron", "~> 0.4.0" 然后 bundle install
  • ActiveJob adapter 设置
    由于我们是结合 Rails 中的 ActiveJob gem 使用,所有我们要在 config/application.rb 中设置后台任务的后端为 sidekiq config.active_job.queue_adapter = :sidekiq,另外,不建议再设置这个配置了 config.active_job.queue_name_prefix,我把它注释了,如果你设置了,那么在下文提到的 sidekiq_schedule.ymlsidekiq.yml 配置文件中中需要注意 queue 的设置。
  • sidekiq 设置
    初始化文件设置,主要是 redis 和 Sidekiq-Cron yaml 配置文件的设置,根据需要可做适当修改。
    # config/initializers/sidekiq.rb
    Sidekiq.configure_client do |config|
      config.redis = { url: 'redis://127.0.0.1:6379/0/cache', namespace: 'wallet_server'  }
    end
    
    Sidekiq.configure_server do |config|
      config.redis = { url: 'redis://127.0.0.1:6379/0/cache', namespace: 'wallet_server'  }
      schedule_file = "config/sidekiq_schedule.yml"
      if File.exists?(schedule_file) && Sidekiq.server?
        Sidekiq::Cron::Job.load_from_hash! YAML.load_file(schedule_file)
      end
    end
    
    然后就是 sidekiq 配置文件设置
    # config/sidekiq.yml
    :pidfile: ./tmp/pids/sidekiq.pid
    :logfile: ./log/sidekiq.log
    :concurrency: 10
    :queues:
      - get_rake
      - minconf
      - send_mail 
    
    sidekiq 配置文件需要注意的一个地方就是 concurrency 的设置,推荐阅读 了解一下具体原因。
  • Sidekiq-cron 定时任务配置文件设置,下面给出一个参考,在实际项目中对应修改即可

// config/sidekiq_schedule.yml
get_rake_job:
description: "get rake every 1 min"
cron: "*/1 * * * "
class: "GetRakeJob"
queue: get_rake
active_job: true
minconf_job:
description: "get minconf every 5 min"
cron: "
/5 * * * *"
class: "MinconfJob"
queue: minconf
active_job: true

以上就是一些设置,接下来讨论 ActiveJob 相关的知识。

### ActiveJob 使用
在 Rails 中使用 ```rails g job get_rake``` 命令可生成一个 app/jobs/get_rake_job.rb 文件。  
```ruby
class GetRakeJob < ApplicationJob
queue_as :get_rake

def perform(*args)
  BlockChainWallet::AppLogger.info "====start assets rake job============"
  Rails.cache.write("btc_rake", Account.asset_rake("btccny", 
  Rails.cache.write("eth_rake", Account.asset_rake("ethcny", 
  Rails.cache.write("sdc_rake", Account.asset_rake("sdccny", 
  Rails.cache.write("peb_rake", Account.asset_rake("pebkrw", SettingConfig.loicoin_api).to_f.krw_to_usd)
  Rails.cache.write("cfc_rake", Account.asset_rake("cfckrw", SettingConfig.loicoin_api).to_f.krw_to_usd)
  BlockChainWallet::AppLogger.info "====get assets rake job done============"
  # Do something later
end
end
before_enqueue
around_enqueue
after_enqueue
befer_perform
around_perform
after_perfom

官方给出的一个回调使用例子

class GuestsCleanupJob < ApplicationJob
  queue_as :default
   
  before_enqueue do |job|
    # Do something with the job instance
  end
            
  around_perform do |job, block|
    # Do something before perform
    block.call
    # Do something after perform
  end
   
  def perform
    # Do something later
  end
end

定时任务启动及停止

  • 启动
    bundle exec sidekiq -C config/sidekiq.yml -e production -d
  • 停止
    sidekiqctl stop tmp/pids/sidekiq.pid 0 -e production

上面两个命令要在项目的根目录下执行。

推荐阅读: