Bra*_*don 9 queue ruby-on-rails redis sidekiq
下午好,
我有两个独立但相关的应用程序.它们都应该有自己的后台队列(阅读:单独的Sidekiq和Redis进程).但是,我偶尔能够把工作推到app2
队列中app1
.
从简单的队列/推送角度来看,如果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!'])
Run Code Online (Sandbox Code Playgroud)
然而,考虑到我已经调用了a Sidekiq.configure_client
和Sidekiq.configure_server
from app1
,可能在这里需要发生一些事情.
显然,我可以直接从Sidekiq内部获取序列化和规范化代码,并手动推送到app2
redis队列,但这似乎是一个脆弱的解决方案.我希望能够使用该Client.push
功能.
我想我的理想解决方案就像:
SidekiqTWO.configure_client { remote connection..... }
SidekiqTWO::Client.push(job....)
甚至:
$redis_remote = remote_connection.....
Sidekiq::Client.push(job, $redis_remote)
显然有点滑稽,但那是我理想的用例.
谢谢!
所以有一点是根据FAQ,"Sidekiq消息格式非常简单和稳定:它只是一种JSON格式的哈希." 强调我的 - 我不认为向sidekiq发送JSON太脆弱了.特别是当你需要细粒度控制你周围发送作业的Redis实例时,就像OP的情况一样,我可能只是写一个小包装器,让我指示一个Redis实例以及正在排队的作业.
对于凯文·比德尔的更普遍的情况,循环作业到Redis的情况下,我想你不希望有其中的Redis实例used--你只是想排队,并有分布自动管理控制.它看起来像只有一个人有此要求,到目前为止,和他们想出了一个解决方案,它使用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
Run Code Online (Sandbox Code Playgroud)
另一件事是在你的追求考虑,以获得高可用性和故障转移是让Sidekiq专业,其中包括可靠性的特点:"在Sidekiq专业客户能承受瞬时Redis的中断将本地排队工作时的错误,并尝试提供这些就业机会一旦连接恢复." 由于sidekiq无论如何都是用于后台进程,如果Redis实例关闭,短暂的延迟不应该影响您的应用程序.如果您的两个Redis实例中的一个出现故障并且您正在使用循环法,那么除非您正在使用此功能,否则您仍然会丢失一些作业.
归档时间: |
|
查看次数: |
3354 次 |
最近记录: |