我正在使用兔子 gem 将消息发布到 RabbitMQ。
按照官方文档中给出的与 Passenger in Rack 应用程序一起使用的建议,我添加了要在新的工作进程启动后执行的连接创建。
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
# We’re in a smart spawning mode
# Now is a good time to connect to RabbitMQ
#
# Every process will get it's own connection!
$rabbitmq_connection = Bunny.new rabbit[settings.environment.to_s]
$rabbitmq_connection.start
end
end
else # For non passenger environments - e.g. specs or rackup
$rabbitmq_connection = Bunny.new rabbit[settings.environment.to_s]
$rabbitmq_connection.start
end
这工作得很好,但是当连接在请求中丢失时(在消息可以发布之前),不会捕获到异常。该过程似乎死了并返回了通用的 apache 错误页面 - 日志记录也不再起作用。
因此,在我的特定情况下,创建了一个数据库条目,但我无法清楚地写出一条日志消息,指示该日志消息以及无法发布的消息。
我发现的一种解决方法是通过在实际发布消息之前直接建立连接,在每个请求的基础上创建到 rabbitmq 的连接。不过,这似乎不是很有效,因为乘客工作进程在被丢弃之前会处理多个请求。然而,它确实正确地捕获了异常,记录它并继续处理请求
def publish_message(exchange, key, message)
rabbitmq_connection = Bunny.new $rabbit
rabbitmq_connection.start
ch = rabbitmq_connection.create_channel
exchange = ch.exchange(exchange, durable: true, type: :topic)
exchange.publish(message, routing_key: key, persistent: true)
ch.close
rabbitmq_connection.close
rescue Exception => e
$log_file.error "Sending message #{message} to #{exchange} with key #{key} failed: #{e.message}"
end
现在我想知道在遵循推荐的方法时如何捕捉到这一点,以及是否还有其他我尚未找到的带有乘客的机架应用程序的最佳实践。我很感激任何提示让我找到比我的解决方法更好的解决方案。