Rails打造微服務之RabbitMQ

MQ 全稱爲 Message Queue, 消息隊列(MQ)是一種應用程序對應用程序的通信方法。應用程序通過讀寫出入隊列的消息(針對應用程序的數據)來通信,而無需專用連接來鏈接它們。

RabbitMQ 是一個在 AMQP 基礎上完整的,可複用的企業消息系統。他遵循 Mozilla Public License 開源協議。

RabbitMQ WIKI:https://zh.wikipedia.org/zh/RabbitMQ

RabbitMQ 百科:http://baike.baidu.com/view/4095865.htm

RabbitMQ 官網:http://www.rabbitmq.com/

RabbitMQ 官網下載:http://www.rabbitmq.com/download.html

RabbitMQ 官網安裝文檔:http://www.rabbitmq.com/install-rpm.html

RabbitMQ 文檔:

優先:http://www.rabbitmq.com/getstarted.html

次要:http://www.rabbitmq.com/documentation.html

安裝( 參考:https://ruby-china.org/topics/35230 | https://www.jianshu.com/p/30b6193785dc)

Gemfile

gem 'standby' # pgbouncer 數據庫讀寫分離

#悲觀鎖  "select * from where xxx for update"
#樂觀鎖  add_column :destinations, :lock_version, :integer 更多(http://hedengcheng.com/?p=771)
gem 'with_advisory_lock' #狀態鎖  行鎖(with_lock) 

gem 'bunny' #client

gem 'sneakers' #service

client demo bunny_service.rb

class BunnyService

  def initialize queue
    @queue = queue
    @amqp_url = $setting['amqp']['url']
  end

  def push message
    begin
      conn = Bunny.new(@amqp_url)
      conn.start
      ch = conn.create_channel
      q  = ch.queue(@queue, :durable=> true, :auto_delete => false)
      q.publish(message.to_json)
      conn.close
    rescue => e
      $logger.info("FATAL bunny push fail: #{e.message}")
    end
  end

  #低於3.5.3的版本需要安裝插件 https://www.cloudamqp.com/docs/delayed-messages.html
  def delay message, expire_time
    begin
      conn = Bunny.new(@amqp_url)
      conn.start
      ch = conn.create_channel
      expire_time *= 1000
      dlx_queue = "dlx_#{@queue}_#{expire_time}"
      q = ch.queue(dlx_queue, arguments: {
        'x-dead-letter-exchange' => '',
        'x-dead-letter-routing-key' => @queue,
        'x-message-ttl' => expire_time
      })
      q.publish(message.to_json, routing_key: dlx_queue)
      conn.close
    rescue => e
      $logger.info("FATAL bunny delay fail: #{e.message}")
    end
  end

  def delete
    begin
      conn = Bunny.new(@amqp_url)
      conn.start
      ch = conn.create_channel
      ch.queue_delete(@queue)
    rescue => e
      $logger.info("FATAL bunny delete fail: #{e.message}")
    end
  end

end

service demo

config/initializers/sneaker.rb

require Rails.root.join('config', 'initializers', 'setting')

opts = {
  daemonize: true,
  amqp: $setting['amqp']['url'],
  log: "log/sneakers.log",
  pid_path: "tmp/pids/sneakers.pid",
  threads: $setting['amqp']['threads'],
  workers: $setting['amqp']['workers'],
  timeout_job_after: 2.minutes,      # Maximal seconds to wait for job
  prefetch: 8,                       # Grab 10 jobs together. Better speed.
  ack: true,
  share_threads: true
}

Sneakers.configure(opts)
Sneakers.logger.level = Logger::INFO

workers/service_worker.rb

class ServiceWorker
  include Sneakers::Worker
  from_queue "worker.you_worker_name.queue"

  def work msg
    message = JSON.parse msg
    begin
      #doing message
    rescue => e
      e.message
    end
    ack!
  end

end

start

bundle exec rake sneakers:run RAILS_ENV=production
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章