【问题标题】:How to migrate from DelayedJob to Sidekiq如何从 DelayedJob 迁移到 Sidekiq
【发布时间】:2014-02-09 11:33:49
【问题描述】:

我的应用可以使用 DelayedJob,但速度很慢,所以我决定改用 Sidekiq。

到目前为止,它还不能用于 Sidekiq 的测试或开发。 (当然,我还没有尝试使用 Sidekiq 进行生产。)

从 DelayedJob 迁移到 Sidekiq 时,我首先更新了我的 Profile

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
# worker:  bundle exec rake jobs:work
before_fork do |server, worker|
   @sidekiq_pid ||= spawn("bundle exec sidekiq -c 2")
end

我假设这意味着我不必在foreman start 之前输入bundle exec sidekiq,对吧?这也应该在我运行测试时启动 sidekiq,对吧?

但在我的测试中,我的应用程序中表示为 @instance.delay.method 的所有内容(应该与 DelayedJob 和 Sidekiq 一起使用)都不起作用。

因此,为了了解正在发生的事情,我在routes.rb 中添加了以下内容:

Testivate::Application.routes.draw do
  require 'sidekiq/web'
  mount Sidekiq::Web, at: "/sidekiq"

但是当我重新启动并访问 localhost:3000/sidekiq 时,我只看到:

No route matches [GET] "/sidekiq"
Routes
Routes match in priority from top to bottom
Helper  HTTP Verb   Path    Controller#Action
Path / Url          
sidekiq_web_path         /sidekiq    Sidekiq::Web

顺便说一句,redis 似乎在本地自动运行:

$ redis-cli ping
PONG

我捆绑的gemfile 包括:

ruby "2.0.0"
gem "rails", "4.0.2"
gem 'sinatra', require: false
gem 'slim'
gem "sidekiq"
gem "autoscaler"

我没有对unicorn.rb进行任何更改:

# config/unicorn.rb
worker_processes 3
timeout 360
preload_app true

before_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

【问题讨论】:

    标签: heroku redis unicorn sidekiq


    【解决方案1】:

    我自己从 DJ 转到 Sidekiq。尽管我在您的配置中看不到任何明显的内容,但我会分享我的有效设置。关于如何配置 Sidekiq 的一些建议。希望这会有所帮助。

    对于初始化程序/redis.rb,支持本地和 heroku 环境:

    module MyRedis
      class << self
          def redis
            @redis ||= Redis.new(url: (ENV['REDISTOGO_URL'] || 'redis://127.0.0.1:6379'))
          end
    
          ##
          # test for avail
          #         
          def sidekiq?
           begin
            redis_info = Sidekiq.redis { |conn| conn.info }
            true
           rescue
            false
           end
          end
       end
    end
    

    对于initilizers/sidekiq.rb(考虑参数化size

    Sidekiq.configure_server do |config|
      config.redis = { :url => MyRedis.redis[:url], :namespace => 'sidekiq', :size => 4 }
    end
    
    Sidekiq.configure_client do |config|
      config.redis = { :url => MyRedis.redis[:url], :namespace => 'sidekiq', :size => 1 }
    end
    

    一个典型的config/sidekiq.yml:

    :verbose: false
    :concurrency:  25
    :queues:
     - [often, 7]
     - [default, 5]
     - [seldom, 3]
    

    然后在你的 Procfile 中,sidekiq.yml:

    web: bundle exec unicorn -p $PORT -E $RAILS_ENV -c ./config/unicorn.rb
    worker: bundle exec sidekiq -C config/sidekiq.yml -e $RAILS_ENV
    

    最后,我对 config/unicorn.rb 所做的唯一更改是在分叉时处理 redis 连接:

     ...
     before_fork do |server, worker|
    
       if defined?(MyRedis.redis)
         MyRedis.redis.quit
         Rails.logger.info('Disconnected from Redis')
       end 
    
    
     ...
     after_fork do |server, worker|
    
       if defined?(MyRedis.redis)
         MyRedis.redis.client.reconnect
         Rails.logger.info('Connected to Redis')
       end       
    

    【讨论】:

    • 25 个线程共享的 4 个 Redis 连接太少了。将并发性降低到 6-8 或将初始化程序中的服务器池大小提高到 15 或更多。连接池是惰性的,因此它只会在运行时创建实际需要的连接数。
    猜你喜欢
    • 2017-12-15
    • 2016-09-30
    • 2018-06-23
    • 2021-07-18
    • 2019-11-11
    • 2018-10-28
    • 2010-10-13
    • 2018-10-25
    • 2019-05-31
    相关资源
    最近更新 更多