我有一个RabbitMQ和Sneakers gem的用例,我有多个Worker在我的项目中运行以响应几十个队列。因此,工作人员很可能同时处理来自同一队列的消息。
特别是有一个队列 - 让我们称之为:one_at_a_time
- 我只希望一个工作人员能够在任何给定时间处理来自队列的消息。
我想这样做的原因是因为工作人员的目的是执行以下操作:
true
,则ack!
消息。false
,请向用户发送电子邮件,然后将:worked
设置为true。这是为了在我使用相同的对象ID快速连续创建两条消息时,我不会意外地向用户发送两次电子邮件。如果在任何给定时间只有一个工作人员听过这个队列,这个设计就可以正常工作,因为第一次运行会经过步骤1 - > 2 - > 2,然后下一次运行将经历步骤1 - > 2 - > 1并且不会向用户发送电子邮件。但是在测试中,我发现存在竞争条件的可能性,其中两个工作人员将同时从:one_at_a_time
队列中提取消息,超过:worked
设置的检查,并且两者都是发送电子邮件。
所有这些都考虑到了,有没有办法可以限制收听队列的工作人员数量?谢谢。
答案 0 :(得分:0)
有关更多参考,可以按照以下步骤将Argus9的请求存档:
1)您可以控制工人的选择:
class YourWorker
include Sneakers::Worker
from_queue "your_queue",
:env => nil,
:ack => true,
:workers => 1, #Number of per-cpu processes to run
:prefetch => 1, #This param will define that single message will be fetched per time
:threads => 1, #This will define that you have single thread running
:heartbeat => 2,
:share_threads => true,
:timeout_job_after => 3600,
:exchange => 'your_exchange'
def work(args={})
#... your steps here
end
end
2)您需要注意在Sneakers.rb中指定的初始参数(初始值由Sneakers :: Runner在工作人员初始化时使用),因此请确保其中包含正确的参数,例如:
Sneakers.configure :amqp => url,
:daemonize => true,
:ack => true,
:prefetch => 1,
:threads => 1,
:start_worker_delay => 0.1,
:workers => 1,
:exchange => "your_exchange",
:exchange_type => :direct,
:log => "log/sneakers.log"
Sneakers.logger.level = Logger::DEBUG
您还可以使用RabbitMQ API构建一些额外的控件,这将使您能够检查诸如是否已在处理某些消息之类的东西?...等等。使用bunny等进行归档并不那么容易。 使用非常简单的代码,例如:
def queue_info
queues_infos = {}
rabbitmqctl_url = "http://127.0.0.1:15672"
rabbitmqctl_user = "your_user"
rabbitmqctl_password = "your_password"
uri = URI.parse("#{rabbitmqctl_url}/api/queues")
request = Net::HTTP::Get.new(uri)
request.basic_auth(rabbitmqctl_user, rabbitmqctl_password)
req_options = { use_ssl: uri.scheme == 'https' }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
queue_details = JSON.parse(response.body)
queue_details.each do |queue|
queues_infos[queue['name'].to_s] = { name: queue['name'],
msg_total: queue['messages'],
msg_ready: queue['messages_ready'],
msg_unacknowlged: queue['messages_unacknowledged'],
state: queue['state'],
consumers: queue['consumers'] }
end
return queues_infos
end