比方说,我需要对100个用户进行复杂的计算。我当前的配置如下:
制作人
class Producer
class << self
def publish(target, options = {})
connection = Bunny.new(some_params).start
channel = connection.create_channel
exchange = channel.fanout("#{target}_exchange", durable: true)
exchange.publish(options.to_json)
end
end
end
MassComplexCalculations工作器
module UsersWorkers
class MassComplexCalculations
include Sneakers::Worker
from_queue "#{ENV['RAILS_ENV']}.users.mass_complex_calculations_queue",
exchange: "#{ENV['RAILS_ENV']}.users.mass_complex_calculations_exchange"
def work(options)
parsed_options = JSON.parse(options)
ActiveRecord::Base.connection_pool.with_connection do
User.where(id: parsed_options['ids']).each do |user|
::Services::Users::ComplexCalculations.call(user)
end
end
ack!
end
end
end
运行工作者
Producer.publish("#{ENV['RAILS_ENV']}.users.mass_complex_calculations", ids: User.limit(100).ids)
我不太了解AMQP如何分配资源来执行任务以及如何提供帮助。是对的,最好在单独的工作程序中运行每个计算?例如:
已更改MassComplexCalculations工作者
module UsersWorkers
class MassComplexCalculations
include Sneakers::Worker
from_queue "#{ENV['RAILS_ENV']}.users.mass_complex_calculations_queue",
exchange: "#{ENV['RAILS_ENV']}.users.mass_complex_calculations_exchange"
def work(options)
parsed_options = JSON.parse(options)
ActiveRecord::Base.connection_pool.with_connection do
parsed_options['ids'].each do |id|
Producer.publish("#{ENV['RAILS_ENV']}.users.personal_complex_calculations", id: id)
end
end
ack!
end
end
end
新的PersonalComplexCalculations工作器
module UsersWorkers
class PersonalComplexCalculations
include Sneakers::Worker
from_queue "#{ENV['RAILS_ENV']}.users.personal_complex_calculations_queue",
exchange: "#{ENV['RAILS_ENV']}.users.personal_complex_calculations_exchange"
def work(options)
parsed_options = JSON.parse(options)
user = User.find(parsed_options['id'])
ActiveRecord::Base.connection_pool.with_connection do
::Services::Users::ComplexCalculations.call(user)
end
ack!
end
end
end
据我了解,可能有两个选择:
那么哪种方法更好?也许甚至其中之一是完全错误的?
谢谢。
答案 0 :(得分:0)
您的假设均不成立。您不能保证会有100个并行工作器,因为运动鞋的默认线程池大小不一定要覆盖:
https://github.com/jondot/sneakers/blob/master/lib/sneakers/worker.rb#L20
如果您没有为ActiveRecord连接池配置至少100个连接,则由于此处资源匮乏,您的代码也会阻塞并等待。
在一般情况下,大多数情况下并行执行此类任务可能在大多数情况下会更快[em] -但这不能保证。