加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 使用sidekiq处理两个独立的redis实例?

发布时间:2020-12-16 19:06:40 所属栏目:百科 来源:网络整理
导读:下午好, 我有两个独立但相关的应用程序.他们都应该有自己的背景队列(阅读:单独的Sidekiq和Redis进程).但是,我偶尔能够从app1将作业推送到app2的队列中. 从简单的队列/推送角度来看,如果app1没有现有的Sidekiq / Redis堆栈,那么很容易做到这一点: # In a pr
下午好,

我有两个独立但相关的应用程序.他们都应该有自己的背景队列(阅读:单独的Sidekiq和Redis进程).但是,我偶尔能够从app1将作业推送到app2的队列中.

从简单的队列/推送角度来看,如果app1没有现有的Sidekiq / Redis堆栈,那么很容易做到这一点:

# In a process,far far away

# Configure client 
Sidekiq.configure_client do |config|
  config.redis = { :url => 'redis://redis.example.com:7372/12',:namespace => 'mynamespace' }
end

# Push jobs without class definition 
Sidekiq::Client.push('class' => 'Example::Workers::Trace','args' => ['hello!'])

# Push jobs overriding default's 
Sidekiq::Client.push('queue' => 'example','retry' => 3,'class' =>     'Example::Workers::Trace','args' => ['hello!'])

但是考虑到我已经从app1调用了Sidekiq.configure_client和Sidekiq.configure_server,可能会在这里介入需要发生的事情.

显然,我可以直接从Sidekiq内部获取序列化和规范化代码,并手动推送到app2的redis队列,但这似乎是一个脆弱的解决方案.我希望能够使用Client.push功能.

我想我的理想解决方案就像:

SidekiqTWO.configure_client {remote connection …..}
SidekiqTWO :: Client.push(作业….)

甚至:

$redis_remote = remote_connection …..

Sidekiq :: Client.push(job,$redis_remote)

显然有点滑稽,但那是我理想的用例.

谢谢!

解决方法

所以有一点是 According to the FAQ,“Sidekiq消息格式非常简单和稳定:它只是JSON格式的Hash.”强调我的 – 我不认为向sidekiq发送JSON太脆弱了.特别是当你想要对你发送作业的Redis实例进行细粒度控制时,就像OP的情况一样,我可能只是编写一个小包装器,让我指示一个Redis实例以及正在排队的作业.

对于Kevin Bedell更常见的情况来将作业循环到Redis实例中,我想你不想控制使用哪个Redis实例 – 你只想排队并自动管理分发.看起来像only one person has requested this so far和they came up with a solution使用Redis::Distributed

datastore_config = YAML.load(ERB.new(File.read(File.join(Rails.root,"config","redis.yml"))).result)

datastore_config = datastore_config["defaults"].merge(datastore_config[::Rails.env])

if datastore_config[:host].is_a?(Array)
  if datastore_config[:host].length == 1
    datastore_config[:host] = datastore_config[:host].first
  else
    datastore_config = datastore_config[:host].map do |host|
      host_has_port = host =~ /:d+z/

      if host_has_port
        "redis://#{host}/#{datastore_config[:db] || 0}"
      else
        "redis://#{host}:#{datastore_config[:port] || 6379}/#{datastore_config[:db] || 0}"
      end
    end
  end
end

Sidekiq.configure_server do |config|
  config.redis = ::ConnectionPool.new(:size => Sidekiq.options[:concurrency] + 2,:timeout => 2) do
    redis = if datastore_config.is_a? Array
      Redis::Distributed.new(datastore_config)
    else
      Redis.new(datastore_config)
    end

    Redis::Namespace.new('resque',:redis => redis)
  end
end

为了获得高可用性和故障转移,需要考虑的另一件事是获得Sidekiq Pro,其中包括可靠性功能:“Sidekiq Pro客户端可以承受瞬态Redis中断.它会在出错时在本地排队作业并尝试一次性提供这些作业连通性得到恢复.“由于sidekiq无论如何都是用于后台进程,如果Redis实例出现故障,短暂延迟不应影响您的应用程序.如果您的两个Redis实例中的一个出现故障并且您正在使用循环法,那么除非您使用此功能,否则您仍然会丢失一些工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读