一、简介
AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。从整体来看, AMQP 协议可划分为三层。这种分层架构类似于 OSI 网络协议,可替换各层实现而不影响与其它层的交互。 AMQP 定义了合适的服务器端域模型,用于规范服务器的行为 (AMQP 服务器端可称为 broker) 。
Model 层决定这些基本域模型所产生的行为,这种行为在 AMQP 中用 ”command” 表示。 Session 层定义客户端与 broker 之间的通信 ( 通信双方都是一个 peer ,可互称做 partner) ,为 command 的可靠传输提供保障。 Transport 层专注于数据传送,并与 Session 保持交互,接受上层的数据,组装成二进制流,传送到 receiver 后再解析数据,交付给 Session 层。 Session 层需要 Transport 层完成网络异常情况的汇报,顺序传送 command 等工作。
RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
较其他MQ优势:1> Apache ActiveMQ曝光率最高,但是可能会丢消息。2> ZeroMQ延迟很低、支持灵活拓扑,但是不支持消息持久化和崩溃恢复。
二、几个重要的概念
Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程,启动服务其实就是启动broker;默认是单节点,可设置集群及镜像防止单节点挂掉使得Queue挂起,有兴趣的可自行百度或以后学习后分享。
Virtual Host:其是一个虚拟概念,类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,但是权限控制的最小粒度是Virtual Host
Producers: 发送消息给exchange(生产者注册exchange)
Exchanges: 用于路由消息(消息发给exchange,exchange发给对应的queue)。路由就是比较routing-key(这个message提供)和binding-key(这个queue注册到exchange的时候提供)。使用时,需要指定exchange的名称和类型(direct,topic和fanout)。
(可通过管理界面查看exchange的属性,D代表持久化、AD代表自动删除、I代表内部exchange。自动删除的exchange在服务重启后自动创建(测试情况是这样);当一个exchange即是自动删除又是持久化的,不会被自动删除;
)
Consumers: consumer需要声明一个queue,并将queue与指定的exchange绑定,然后从queue里面接收消息
Queues: 接收exchange发过来的消息
Routing keys: 每个消息在发送时都会声明一个routing_key。routing_key的含义依赖于exchange的类型。一般说来,在AMQP标准里定义了四种默认的exchange类型,此外,vendor还可以自定义exchange的类型。但是,我们下面只关注AMQP 0.8版本中定义的三种默认exchange类型,也是最常用的三类exchange
Direct exchange: 如果message的routing_key和某个consumer中的routing_key相同,就会把消息发送给这个consumer监听的queue中。
Fan-out exchange: 广播模式。exchange将收到的message发送到所有与之绑定的queue中。
Topic exchange: 该类型exchange会将message发送到与之routing_key类型相匹配的queue中。routing_key由一系列“.”隔开的word组成,“*”代表匹配任何word,“#”代表匹配0个或多个word,类似于正则表达式。
在RabbitMQ中,发送是将指定完exchange、routing_key以及其他一些属性的message用channel.basic_publish方法来实现的,接收则是声明一个queue然后与exchange绑定,并指定callback函数。而在Kombu中消息的发送和接收则会更加简单和形象。
三、测试相关:目前可能遇到的问题
数据被消费了,不知道消息是否被推送,以及推送的内容是否正确;这样只能通过查日志的方式来确认,比较费事。
此时可以建立copy队列来解决,同时可以通过页面建立,一般填个名字,选择是否持久化跟自动删除;
然后点击进入详情页操作绑定exchange及routing key,这样就可以接受消息,通过页面来get message
再者copy队列数据太多,不好get;如果不关心原数据可直接从页面清空,继续造新数据,使用purge操作。delete为删除queue(exchange也可删除),使用时注意。
如果不想清空原数据,此时可以创建消费者,将已推送消息进行处理或者存储
开发测试过程中遇到依赖上游系统数据,切通过mq异步方式的,在上游系统不方便配合,或者功能未完全完数据无法推送情况。
在知道数据体格式规则的情况,可以自行向mq中推送数据,将测试流程执行下去;当然通过queue详情页面的publish message也可实现
测试时还需注意消费者的情况,防止非测试要求的机器消费了queue中信息,导致影响测试
再着,mq是异步的,可能导致消息传递顺序的颠倒,如果是需顺序处理数据,需保证此种情况数据不出现错误,比如一条数据的“已删除”状态先与“已通过”接收,消息处理后数据状态需为“已删除”
再一点,测试异常消息的处理,比如数据格式变更无法解析时,如果是需要消费后自行确认的的queue,在收到消费者确认前不会删掉message,会导致消息堆积。因此需要有错误数据的处理机制
参考来源
http://www.rabbitmq.com/getstarted.html
http://blog.csdn.net/lmj623565791/article/category/2386657
http://www.diggerplus.org/archives/3110
http://www.cnblogs.com/uptothesky/p/6094357.html
http://www.cnblogs.com/hanyouchun/p/5383548.html
http://www.tuicool.com/articles/6BRzMji