0

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 の両方で行う必要がある構成設定はありますか?

ありがとう。

編集

  1. このページ ( http://rubyamqp.info/articles/getting_started/ ) の「Hello World」の例をrails cコンソールで実行すると、非常に高速です。

  2. 私はすでに設定しましたulimit -n 1024

  3. next_tick以下のようにすればrails c、超高速です:

=========

require "rubygems"
require "amqp"

EventMachine.run do
  EventMachine.next_tick {
    puts "next_tick triggerred"
  }
end

=========

4

0 に答える 0