Ruby on Rails アプリに AMQP / RabbitMQ を使用しています。
amqp.rb
次のファイルを下に置きましたconfig/initializers
:
require 'amqp'
# References:
# 1. Getting Started with AMQP and Ruby
# http://rubyamqp.info/articles/getting_started/
# 2. EventMachine and Rails
# http://www.hiringthing.com/2011/11/04/eventmachine-with-rails.html#sthash.iqCWUtOn.dpbs
# 3. Connecting to the broker, integrating with Ruby on Rails, Merb and Sinatra
# http://rubyamqp.info/articles/connecting_to_broker/
module AppEventMachine
def self.start
if defined?(PhusionPassenger)
Rails.logger.info "###############################################################################"
Rails.logger.info "Running EventMachine/Rails with PhusionPassenger ......"
Rails.logger.info "###############################################################################"
PhusionPassenger.on_event(:starting_worker_process) do |forked|
# => for passenger, we need to avoid orphaned threads
if forked && EventMachine.reactor_running?
EventMachine.stop
end
spawn_eventmachine_thread
die_gracefully_on_signal
end
else
Rails.logger.info "###############################################################################"
Rails.logger.info "PhusionPassenger is not running. Probably you are running Rails locally ......"
Rails.logger.info "###############################################################################"
# faciliates debugging
Thread.abort_on_exception = true
# just spawn a thread and start it up
spawn_eventmachine_thread unless defined?(Thin)
# Thin is built on EventMachine, doesn't need this thread
end
end
def self.spawn_eventmachine_thread
Thread.new {
EventMachine.run do
AMQP.channel ||= AMQP::Channel.new(AMQP.connect(:host => '127.0.0.1')) # Q_SERVER, :user=> Q_USER, :pass => Q_PASS, :vhost => Q_VHOST ))
AMQP.channel.on_error(&method(:handle_channel_exception))
AMQP.channel.queue(MixpanelJob::QUEUE_NAME, :exclusive => true)
.subscribe(&method(:handle_sending))
end
}
end
def self.handle_sending(metadata, payload)
puts "handle_sending: ######################"
Rails.logger.info "Received a message: #{payload}, content_type = #{metadata.content_type}"
Rails.logger.info "Sending to the Mixpanel server ......"
# In a worker process on this/another machine
Rails.logger.info "Sent the message to the Mixpanel server ......"
end
def self.handle_channel_exception(channel, channel_close)
Rails.logger.error "###############################################################################"
Rails.logger.error "Oops... a channel-level exception: code = #{channel_close.reply_code}, message = #{channel_close.reply_text}"
Rails.logger.error "###############################################################################"
end
def self.die_gracefully_on_signal
Rails.logger.error "###############################################################################"
Rails.logger.error "Stopping the EventMachine ......"
Signal.trap("INT") { EventMachine.stop }
Signal.trap("TERM") { EventMachine.stop }
Rails.logger.error "###############################################################################"
end
end
AppEventMachine.start
サブスクライブ ハンドラhandle_sending
が応答するまでに長い時間がかかります (数分または 10 分以上)。
これは正常ですか?AMQP または RabbitMQ の両方で行う必要がある構成設定はありますか?
ありがとう。
編集
このページ ( http://rubyamqp.info/articles/getting_started/ ) の「Hello World」の例を
rails c
コンソールで実行すると、非常に高速です。私はすでに設定しました
ulimit -n 1024
next_tick
以下のようにすればrails c
、超高速です:
=========
require "rubygems"
require "amqp"
EventMachine.run do
EventMachine.next_tick {
puts "next_tick triggerred"
}
end
=========