消息队列、AMQP和RabbitMQ

一、应用场景及优点

在项目设计、开发过程中,当我们遇到以下几种情况都可以使用消息队列:

  1. 对于一些无需即时返回且耗时的操作;
  2. 并发要求很高,数据处理很耗时,但是又无需及时返回信息的操作;
  3. 数据转移类的操作,比如客户端和内网都要进行数据传输和交换, 现有架构中, 客户端不能直接访问内网, 那么客户端只能: 先把数据保存到外网服务器, 然后内网服务器再拉回来处理. 这种方式可以保证数据都能被处理, 但实效性不够.通常, 外网服务器只起到一个暂时保存数据的作用, 保存客户端报上来的数据, 然后等待内网来拉走,把客户端看做producer, 内网看做consumer, 这正是消息队列的用武之地。

以上几个应用场景仅仅是我的一家之言,可以根据具体业务需求,灵活运用,消息队列更多的是一种解决问题的思路,见仁见智!

消息队列通过消息的生产/订阅,把消息写入消息队列,通过消费者订阅提取出来,对数据进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。

另外消息队列还有两个优点,平台无关性分布式部署;这个也是我个人比较看重的地方.

二、目前消息队列的主流产品

MSMQ:
这是微软的产品里唯一被认为有价值的东西。对我的客户来说,如果MSMQ能证明可以应对这种任务,他们将选择使用它。关键是这个东西并不复杂,除了接收和发送,没有别的;它有一些硬性限制,比如最大消息体积是4MB。然而,通过和一些像MassTransit 或 NServiceBus这样的软件的连接,它完全可以解决这些问题。


ActiveMQ:
Java世界的中坚力量。它有很长的历史,而且被广泛的使用。它还是跨平台的,给那些非微软平台的产品提供了一个天然的集成接入点。然而,它只有跑过了MSMQ才有可能被考虑。

RabbitMQ:
我听说了很多关于这个用Erlang写成的消息中间件的优秀的特性。它支持开放的高级消息队列协议 (AMQP,Advanced Message Queuing Protocol),从根本上避免了生产厂商的封闭,使用任何语言的各种客户都可以从中受益。这种协议提供了相当复杂的消息传输模式,所以基本上不需要MassTransit 或 NServiceBus 的配合。它还具有“企业级”的适应性和稳定性。这些东西对客户来说十分的有吸引力。

我个人也比较偏好使用RabbitMQ,在商业环境中也有使用经验,能够承担商业级应用。

ZeroMQ:
我在研究AMQP时从发现了这个产品。开发这个产品的公司是AMQP集团的一部分,并且还有一个叫做OpenAMQ的产品。然而,他们却戏剧性的从AMQP分离的出去,并抱怨说这这个产品迷失了方向、变的越来越复杂。你可以到这里阅读Dear John的关于此事的文章。ZeroMQ具有一个独特的非中间件的模式,也就是说,跟其它几个接受测试的产品不同,你不需要安装和运行一个消息服务器,或中间件。你只需要简单的引用ZeroMQ程序库,可以使用NuGet安装,然后你就可以愉快的在应用程序之间发送消息了。

三、AMQP

高级消息队列协议(AMQP)是一个异步消息传递所使用的应用层协议规范。作为线路层协议,而不是API(例如JMS),AMQP客户端能够无视消息的来源任意发送和接受信息。现在,已经有相当一部分不同平台的服务器和客户端可以投入使用。

AMQP的原始用途只是为金融界提供一个可以彼此协作的消息协议,而现在的目标则是为通用消息队列架构提供通用构建工具。因此,面向消息的中间件(MOM)系统,例如发布/订阅队列,没有作为基本元素实现。反而通过发送简化的AMQ实体,用户被赋予了构建例如这些实体的能力。这些实体也是规范的一部分,形成了在线路层协议顶端的一个层级:AMQP模型。这个模型统一了消息模式,诸如之前提到的发布/订阅,队列,事务以及流数据,并且添加了额外的特性,例如更易于扩展,基于内容的路由。

四、RabbitMQ

本文中的AMQP服务器是使用Erlang编写的RabbitMQ。它实现了AMQP规范0-8版的内容,并且将在近期实现0-9-1版的内容。

在开始之前再交代一些东西:异步消息是一个非常普通并且广泛使用的技术,从例如Skype或者XMPP/Jabber这样各种各样的即时消息协议到古老的email。

但是,这些服务都有如下特征:

  1. 它们会在传输消息的时候或多或少加入一些随意的内容(例如一封email可能会包含一个文本和关于办公室笑话的PPT)和一些比较正式的路由信息(例如email地址)。
  2. 它们都是异步的,也就是说它们将生产者和消费者区分开来,因此可能将消息加入队列(例如某人发给你一条消息,但是你不在线或者你的邮箱会收到一封email)。
  3. 生产者和消费者是具有不同知识的不同角色。我不需要知道你的IMAP用户名和密码就能够给你发送email。事实上,我甚至不需要知道你的email地址是否是一个马甲或者“真实”地址。这个特性意味着生产者不能控制什么内容被阅读或者订阅了 - 就像我的email客户端会舍弃掉大多数主动发送给我的医药广告。

AMQP是一个抽象的协议(也就是说它不负责处理具体的数据),这个事实并不会将事情变得更复杂。反而,Internet使得消息无处不在。人们通常使用它们和异步消息简单灵活地解决很多问题。而且构建AMQ中的异步消息架构模型最困难的地方在于上手的时候,一旦这些困难被克服,那么构建过程将变得简单。

安装:

需要说明的是,RabbitMQ支持目前主流的所有操作系统,这一点也是吸引我的地方。

  1. Erlang/OTP包,下载地址是 http://erlang.org/download.html,安装说明在 http://www.erlang.org/doc/installation_guide/part_frame.html 。
  2. RabbitMQ,下载地址是 http://www.rabbitmq.com/download.html,安装说明在 http://www.rabbitmq.com/install.html。
  3. Python,simplejson 下载地址: http://www.python.org/getit/,http://pypi.python.org/pypi/simplejson#downloads 。

详细的安装步骤可以参考: 

  1. http://blog.csdn.net/historyasamirror/article/details/6827870
  2. http://www.rabbitmq.com/admin-guide.html

RabbitMQ的文档比较全面,网上资料比较丰富,学习成本相对已经比较低了。


现在你需要做的就是启动RabbitMQ服务器。

 

今天到此为止吧,改天再写关于RabbitMQ的运行机制,后续会出来具体的使用方法,以及我对RabbitMQ的简单实用封装。

 

参考资料:

AMQP和RabbitMQ入门 http://www.infoq.com/cn/articles/AMQP-RabbitMQ

=====================================================================================================
Spring AMQP是什么?介绍一下?
Spring公司收购了RabbitMQ知名消息中间件厂商,之后将RabbitMQ客户端集成到Spring中形成的一个消息队列子模块
如何使用参考:http://www.rabbitmq.com/devtools.html#java-dev
Spring AMQP:http://www.springsource.org/spring-amqp
生产者 ->代理者 ->消费者

原文位置:

http://www.oschina.net/p/rabbitmq

RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang 写成,因此也是继承了这些优点。

AMQP 里主要要说两个组件:Exchange 和 Queue (在 AMQP 1.0 里还会有变动),如下图所示,绿色的 X 就是 Exchange ,红色的是 Queue ,这两者都在 Server 端,又称作 Broker ,这部分是 RabbitMQ 实现的,而蓝色的则是客户端,通常有 Producer 和 Consumer 两种类型:

SpringSource发布了Spring AMQP 1.0的第一个里程碑版本,一个Spring 框架的AMQP消息解决方案。提供模板化的发送和接收消息的抽象层,提供基于消息驱动的 POJO。同时有 Java 和 .NET 的版本。

这个项目包含几个模块,如:spring-amqp, spring-rabbit以及spring-erlang等。


点击此处查看Spring AMQP 1.0 M1 的文档,此版本可支持RabbitMQ 1.8.x。


  • RabbitMQ is an implementation ofAMQP.

ejabberd和RabbitMQ 都使用 Erlang 语言开发, 通过网关它们能很好得集成在一起. 为企业打造一个强大的消息基础设施. 我们建议将它们部署在”云”中, 如 Amazon EC2. 以获得足够的伸缩性.

通过RabbitHub 能连通更多的开放标准, 形成一个更加开放、统一的消息平台.

RabbitHub provides anHTTP-based interface to  RabbitMQ.


========================================================================================================

消息队列

       一个任务运行时的数据和状态怎么告诉其他任务?信号量为任务间同步和互斥提供了提供了高效的方法,但它不能携带更多的任务信息。因而需要使用更高级的通讯方式,即消息队列和管道。这节主要讲消息队列。

消息队列的应用场景:

一对一:

图一 两个任务利用消息通讯

这是一种简单的应用模式。任务1 发送消息到消息队列1 中,任务2 从消息队列中1 接收消息,如果任务2 需要回应消息,就需要再创建一个消息队列2。

 

多对一:

这种多对一的应用模式类似于“客户——服务器”,任务3 作为服务器,侦听来自其它任务(客户)的请求,根据不同的任务和不同的请求内容单独发回应消息

 

    一种同步消息队列模型

在已故巨匠Stevens先生中的<<网络编程卷2>>中有记载使用互斥锁和条件变量来解决生产者/消费者的方法,在多线程编程中,我们也常常需要解决这样的生产者消费者问题。在实际项目中,我见到过很多种解决类似问题的同步消息队列,有的复杂而优雅,有得简陋而实用。

对于生产者,如果不考虑内存和队列的大小问题,只需要一直往消息队列里推消息就可以了。而对于消费者就要复杂一点了,在消息队列取空后,消费者可以循环轮询队列,直到取到新的消息,这种方式编码简单,但是费CPU时间片; 更加优雅的方法是当消息队列为空时,将消费者挂起,等到有消息可读时再唤醒。这里引用Stevens先生的方法,使用互斥锁和信号量实现了一个简单的同步消息队列模型。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值