使用Ruby" bunny" RabbitMQ客户端,我希望我的生产者(一些Ruby代码)向消费者(使用"运动鞋" gem)的工作人员发送消息,并且我希望我的生产者不执行其Ruby代码的另一行直到生产者收到消费者收到我的消息并做了一些工作的确认。
在我的消费者中,我正在做一些工作,然后打电话给运动鞋' ack!
方法确认已收到消息并且工作已完成。
在我的制作人中,我在confirm_select
个实例上调用Bunny::Channel
将其放入确认码中,在publish
我的消息之后,我打电话给wait_for_confirms
应该等到我的所有消息都由消费者ack!
编辑的频道。 (我已尝试实施我在bunny docs here中找到的内容。)
然而,似乎我的制作人并没有等待消费者致电ack!
。我登录了我的制作人和我的消费者,并发现我的制作人似乎认为消息在消费者实际承认之前已被确认。
如何让RabbitMQ制作人等到消费者完成Ruby工作?
Ruby 2.3.3,RabbitMQ 3.6.12,Erlang 17.3。
这是我的锁文件:
GEM
specs:
amq-protocol (2.2.0)
bunny (2.7.0)
amq-protocol (>= 2.2.0)
concurrent-ruby (1.0.5)
serverengine (1.5.11)
sigdump (~> 0.2.2)
sigdump (0.2.4)
sneakers (2.6.0)
bunny (~> 2.7.0)
concurrent-ruby (~> 1.0)
serverengine (~> 1.5.11)
thor
thor (0.20.0)
PLATFORMS
ruby
DEPENDENCIES
bunny
sneakers
BUNDLED WITH
1.14.6
这是我的消费者/工人(consumer_worker.rb
):
class ConsumerWorker
include Sneakers::Worker
from_queue 'do-work-here',
exchange: 'do-work-here',
exchange_type: :direct,
durable: true,
prefetch: 1,
arguments: {
:'x-dead-letter-exchange' => 'do-work-here-retry'
},
timeout_job_after: 5,
retry_timeout: 60000,
ack: true
def work(msg)
open('ruby-debug.log', 'a') do |f|
f.puts "message received: #{msg}"
end
sleep 1
open('ruby-debug.log', 'a') do |f|
f.puts "acknowledging message at: #{Time.now.to_i}"
end
ack!
open('ruby-debug.log', 'a') do |f|
f.puts "acknowledged message at: #{Time.now.to_i}"
end
end
end
在一个终端标签中,我正在运行此工作人员:
bundle exec sneakers work ConsumerWorker --require consumer_worker.rb
以下是我的发布商(publisher.rb
):
require 'bunny'
connection = Bunny.new('amqp://guest:guest@localhost:5672').tap(&:start)
channel = connection.create_channel
channel.confirm_select
queue = channel.queue('do-work-here',
{arguments: {:'x-dead-letter-exchange' => 'do-work-here-retry'},
durable: true})
queue.publish('hello world', persistent: true)
channel.wait_for_confirms
open('ruby-debug.log', 'a') do |f|
f.puts "messages confirmed at: #{Time.now.to_i}"
end
当我在另一个标签中运行以下命令时:
ruby ./publisher.rb
然后我的日志文件(./ruby-debug.log
)包含以下行:
message received: hello world
messages confirmed at: 1505774819
acknowledging message at: 1505774820
acknowledged message at: 1505774820
我想要的是事件的顺序是这样的:
message received
acknowledging message
acknowledged message
messages confirmed
如何解决这个问题?
答案 0 :(得分:0)
发布商确认仅涵盖发布者到RabbitMQ的通信。出版商不了解消费者。
请参阅教程6,了解请求/响应模式的示例: https://www.rabbitmq.com/getstarted.html
ConditionVariable是一种常用的并发原语,用于在事件发生之前延迟进一步的操作,并带有可选的超时。
发布商确认和消费者确认记录在http://www.rabbitmq.com/confirms.htm。