一、安装
Rabbitmq 是用 erlang 语言写的,所以使用还要安装 Erlang。
安装 erlang 还要安装 python 与 simplejson,我环境中已经安装了 python 2.6.4,simplejson 只要 easy_install 就可以了
安装Python、Erlang、SimpleJson请看红薯的博客:http://www.oschina.net/question/12_7840
二、了解
高级消息队列协议(AMQP) 是一个异步消息传递所使用的应用层协议规范。作为线路层协议,而不是API(例如JMS),AMQP 客户端能够无视消息的来源任意发送和接受信息。现在,已经有相当一部分不同平台的服务器和 客户端可以投入使用。
队列是一个先入先出的数据结构。路由封装了消息 队列中的消息的相关信息,这些信息决定了消息在异步消息系统中的最终展现形式。
异步消息是一个非常普通并且广泛使用的技术,从例如Skype或者XMPP/Jabber这样各种各样的即时消息协议到 古老的email。但是,这些服务都有如下特征:
- 它们会在传输消息的时候或多或少加入一些随意的内容(例如一封email可能会包含一个文本和关于办公室笑话的PPT)和一些比较正式的路由信息(例如 email地址):正式的路由信息+随意的信息
- 它们都是异步的,也就是说它们将生产者和消费者区分开来,因此可能将消息加入队列(例如某人发给你一条消息,但是你不在线或者你的邮箱会收到一封 email):不需要等待消息被处理后的返回值
- 生产者和消费者是具有不同知识的不同角色。我不需要知道你的IMAP用户名和密码就能够给你发送email。事实上,我甚至不需要知道你的email地址 是否是一个马甲或者“真实”地址。这个特性意味着生产者不能控制什么内容被阅读或者订阅了 (只管发,不关心消息是否被使用)- 就像我的email客户端会舍弃掉大多数主动发送给我的医药广告。
AMQP是一个抽象的协议(也就是说它不负责处理具体的数据),这个事实并不会将事情变得更复杂。反而,Internet使得消息无处不在。
可配置的实体有:
- 消息协商器(Message Broker),它在TCP/IP等端口监听AMQ消息。
- 将消息协商数据划分到多个不同集合的虚拟主机,它很像webserver中的虚拟主机,例如Apache的http守护进程。
- 使用安全凭据连接到虚拟主机的用户。
值得注意的是,规范中仅仅授予用户访问虚拟主机的权限,并没有采纳其他比这高级的访问控制措施,因此RabbitMQ并不支持这些高级访问控制措 施。--用户角色权限分配目前并不支持,可由厂商扩展。
为了和协商器交流,一个客户端需要建立一个或者多个连接。这些连接只是限于连接用户和虚拟主机。客户端默认使用guest/guest访问权限和访问虚拟主机的根目录,这些默认实现也是RabbitMQ的默认安装选项。
在一个连接中,客户端声明了一个通道,通过单一连接到协商器的并发控制需要建立一个可靠的模型,这里可以使用通道池和串行访问或者例如线程本地通道这样的线程并发模型。
如果需要在一个通道上进行操作,那么客户端需要声明AMQ组件。声明组件是断言特定的组件存在于协商器中──如果不存在的话,那么在运行时创建。
这些组件包括:
- 交换器(Exchange),它是发送消息的实体。
- 队列(Queue),这是接收消息的实体。
- 绑定器(Bind),将交换器和队列连接起来,并且封装消息的路由信息。
客户端可以通过交换器的名字来发送消息,也可以通过队列的名字收取信息。 绑定器没有名字,它们的生命期依赖于所紧密连接的交换器和队列。如果这两者任意一个被删除掉,那么绑定器便失效了。这就说明,若要知道交换器和队列 的名字,还需要设置消息路由。
消息是一个不透明的数据包,这些包有如下性质:
- 元数据-数据的数据(数据描述),例如内容的编码或者表明来源的字段。
- 标志位,标记消息投递时候的一些保障机制。
- 一个特殊的字段叫做routing key。
三、使用 3.1接受和发送消息:交换器类型
发送消息是一个非常简单的过程。客户端声明一个它想要发送消息的目的交换器,然后将消息传递给交换器。接受消息的最简单办法是设置一个订阅。客户端需要声明一个队列,并且使用一个绑定器将之前的交换器和队列绑定起来,这样的话,订阅就设置完毕。
1 require 'rubygems' 2 require 'mq' 3 4 event_loop = Thread.new do 5 EM.run do 6 EM.add_timer(1) do 7 EM.stop 8 end 9 end 10 end 11 12 def subscribe_to_queue 13 14 exchange = MQ.fanout('my-fanout-exchange') 15 queue = MQ.queue('my-fanout-queue') 16 17 queue.bind(exchange).subscribe do |header, body| 18 yield header, body 19 end 20 21 end 22 23 def send_to_exchange(message) 24 25 exchange = MQ.fanout('my-fanout-exchange') 26 exchange.publish message 27 28 end 29 30 subscribe_to_queue do |header, body| 31 p "I received a message: #{body}" 32 end 33 34 send_to_exchange 'Hello' 35 send_to_exchange 'World' 36 37 event_loop.join
三个标准决定了一条消息是否真的被投递到了队列中: