美文网首页开发技术干货
Ruby客户端 操作 rabbitmq-server 技巧

Ruby客户端 操作 rabbitmq-server 技巧

作者: 老码农不上班 | 来源:发表于2016-10-18 20:00 被阅读369次

    RabbitMQ 是一种消息队列,充当接收和传送消息的中间角色。实现了多应用之间相互通讯使用生产者消费者模式。其支持多平台,Linux macOS window ,同时也支持多种语言 Python, Java, Ruby, PHP。其使用场景比较多使用与现阶段讨论比较多的为服务中,把一个大的应用拆分成多个服务,其中使用 RabbitMQ 作为消息队列服务之间进行通信。在这里我们讨论的是如何使用 ruby 实现一个简单的消息队列系统,读者可举一反三。

    安装 RabbitMQ

    • macOS
      根据 官方文档,跟着一步一步来即可。
    • Ubuntu
      rabbitmq-server 依赖 erlang 环境
      sudo apt-get update
      sudo apt-get install erlang
      sudo apt-get install erlang-nox
      sudo apt-get install rabbitmq-server
      
      安装文档

    开启 Web 管理页面 sudo rabbitmq-plugins enable rabbitmq_management

    The following plugins have been enabled:
      mochiweb
      webmachine
      rabbitmq_web_dispatch
      amqp_client
      rabbitmq_management_agent
      rabbitmq_management
    
    Applying plugin configuration to rabbit@i-l9ptvup7... started 6 plugins.
    

    重启 Rabbitmq-server : cd /etc/init.d ; ./rabbitmq-server restart
    安装完毕之后,你可以通过浏览器访问 http://localhost:15672/ 其中有个密码和用户名相同的默认的 guest用户可以登录管理页面,并且该用户只能通过本地 localhost 访问,远程访问是不行的。
    通过 web 图形化页面可以添加用户,另外也可以通过命令行添加

    sudo rabbitmqctl add_user test test
    sudo rabbitmqctl set_user_tags test administrator
    sudo rabbitmqctl set_permissions -p / test ".*" ".*" ".*"
    

    关于服务的一些说明

    发送消息服务,接收消息服务以及 rabbitmq-server 服务可以部署在不同的机器上,当然也可部署在同一台服务器上。有一个场景:譬如我有一个区块链钱包服务(消费者),同时区块链上交易时会发送一个回调(生产者),那么这两个服务可以通过 rabbitmq-server 进行通信。这三个服务能通过远程进行调用从而不需要部署在同一台机器上。

    发送消息(生产者)

    Ruby 有对应的 gem 客户端能和 rabbitmq-server 通信 bunny,安装以及快速使用在 Github 上看文档即可。

    #!/usr/bin/env ruby
    ## encoding: utf-8
    ## send.rb
    
    require "bunny"
    class Send
        def self.publish(exchange, message = "hellooooo")
            x = channel.fanout("blog.#{exchange}")
            x.publish(message)
        end
    
        def self.channel
            @channel ||= connection.create_channel
        end
    
        def self.connection
            @conn = Bunny.new(:automatically_recover => false)
            @conn.start
        end
    end
    
    Send.publish("posts", "hello world ..........")
    

    上面这段代码中,产生了一个 blog:posts 扇形(fanout)交换机。 生产者的服务和 rabbitmq-server 服务部署在同一台机器,如果在不同机器,要把

    @conn = Bunny.new(:automatically_recover => false)
    

    替换成:

    @conn = Bunny.new( :host => "remote_server_ip", :port => "5672", :user => "user_name", :password => "user_passowrd", :automatically_recover => false)
    

    那么到此一个简单的发送 hello world 生产者就构建完成了。
    通过访问 http://localhost:15672/#/exchanges,可以看到 blog:posts 交换机

    后台队列接收消息(消费者)

    如果你用过 sidekiq, 那么这里讨论的内容有点类似,只不过这里的后台队列处理的是消息队列中的信息。
    在这小节中,我们需要用到另外一个 gem sneakers,它的作用和 sidekiq 非常类似,只不过它处理的是从消息队列中传过来的信息。其描述是:

    A fast background processing framework for Ruby and RabbitMQ http://sneakers.io

    安装以及快速使用在 Github 上查阅 readme 和 wiki 即可。

    #!/usr/bin/env ruby
    ## encoding: utf-8
    ## boot.rb
    require 'sneakers'
    Sneakers.configure  ({
        :amqp => 'amqp://user_name:user_password@localhost:5672',
        :exchange => 'sneakers',
        :exchange_type => :direct
    })
    Sneakers.logger.level = Logger::INFO
    class Processor
        include Sneakers::Worker
        from_queue "dashboard.posts"
        def work(msg)
            p msg
            ack!
        end
    end
    

    上面这段代码中,产生了一个 dashboard.posts 队列。访问 http://localhost:15672/#/queues 可以看到。
    如果执行脚本 sneakers work Processor --require boot.rb,在管理页面可以看到

    队列
    但是这个队列没有和任何交换机绑定,此刻发送者和接收者还没产生关系,如果两者要通信,就要把交换机和队列绑定
    这里的绑定有一个脚本
    require "bunny"
    conn = Bunny.new
    conn.start
    ch = conn.create_channel
    # get or create exchange
    x = ch.fanout("blog.posts")
    # get or create queue (note the durable setting)
    queue = ch.queue("dashboard.posts", durable: true)
    # bind queue to exchange
    queue.bind("blog.posts")
    conn.close
    

    如果接收方服务是一个 Rails 应用,那么写个 rake 任务

    namespace :rabbitmq do
      desc "Setup RabbitMQ routing"
      task :setup do
        require "bunny"
    
        conn = Bunny.new
        conn.start
    
        ch = conn.create_channel
    
        # get or create exchange
        x = ch.fanout("blog.posts")
    
        # get or create queue (note the durable setting)
        queue = ch.queue("dashboard.posts", durable: true)
    
        # bind queue to exchange
        queue.bind("blog.posts")
    
        conn.close
      end
    end
    

    执行脚本或者任务(rake rabbitmq:setup) 就能把交换机和队列绑定。
    此时再访问http://localhost:15672/#/queues 可以看到。

    绑定队列

    完整的生产消费过程

    做完上面所有的描述以后,咱们就可以看到 hello world 了,具体如下:

    • 启动接收服务
      sneakers work Processor --require boot.rb
    • 绑定队列和交换机
      rake rabbitmq:setup 在这里是 Rails rake 任务
    • 发送消息
      ruby send.rb
      绑定队列

    推荐阅读:

    相关文章

      网友评论

        本文标题:Ruby客户端 操作 rabbitmq-server 技巧

        本文链接:https://www.haomeiwen.com/subject/eyututtx.html