MQ技术选型
消息中间件的传递模式
一般有两种传递模型:点对点模型(PTP)和发布-订阅模型(Pub/Sub)。
1.点对点模型(PTP)
点对点模型用于消息生产者和消息消费者之间点到点的通信。消息生产者将消息发动到由某个名字标识的特定消费者。这个名字实际上对应于消息服务中的一个队列(),在消息传动给消费者之前它被存储在这个队列中。队列可以是持久的,以保证在消息服务出现故障时仍然能够传递消息。
2.发布-订阅模型(Pub/Sub)
发布-订阅模型用称为主题()的内容分层结构代替了P TP模型中的惟一目的地,发送应用程序发布自己的消息,指出消息描述的是有关分层结构中的一个主题的信息。希望接收这些消息的应用程序订阅了这个主题。订阅包含子主题的分层结构中的主题的订阅者可以接收该主题和其子主题发表的所有消息。
下图展示了发布和订阅模型:
多个应用程序可以就一个主题发布和订阅消息,而应用程序对其他人仍然是匿名的。MOM g e Orie,面向消息的中间件)起着代理(r)的作用,将一个主题已发表的消息路由给该主题的所有订阅者。
常见消息协议
协议
,c ol,是流文本定向消息协议,是一种为O M设计的简单文本协议。
它提供了一个可互操作的连接格式,允许M P客户端与任意O MP消息代理r)进行交互,类似于
e nWi e(一种二进制协议)。
由于其设计简单,很容易开发客户端,因此在多种语言和多种平台上得到广泛应用。其中最流行的P消息代理是
e MQ。
协议工作于T CP协议之上,使用了下列命令:
* SEND 发送
R IBE 订阅
E退订
开始
T提交
取消
* ACK 确认
断开
AMQP协议
AMQP,即c ol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
AMQP在消息提供者和客户端的行为进行了强制规定,使得不同卖商之间真正实现了互操作能力。
JMS是早期消息中间件进行标准化的一个尝试,它仅仅是在A PI级进行了规范,离创建互操作能力还差很远。
与JMS不同,AMQP是一个e级的协议,它描述了在网络上传输的数据的格式,以字节为流。因此任何遵守此数据格式的工具,其创建和解释消息,都能与其他兼容工具进行互操作。
AMQP的实现有:M Q等。
常见消息中间件产品
e MQ
e MQ是一个基于c ed发布,开放源码的J MS产品。其特点为:
1)提供点到点消息模式和发布/订阅消息模式;
2)支持s s、i mo等开源应用服务器,支持i ng框架的消息驱动;
3)新增了一个P2P传输层,可以用于创建可靠的2P JMS网络连接;
4)拥有消息持久化、事务、集群支持等J MS基础设施服务。
t Q
e nt: t q/2.2.14.Fina-
.html
t Q是一个支持集群和多种协议,可嵌入、高性能的异步消息系统。t Q完全支持JMS,t Q不但支持.1 API同时也定义属于自己的消息A PI,这可以最大限度的提升t Q的性能和灵活性。在不久的将来更多的协议将被支持。
t Q拥有超高的性能,t Q在持久化消息方面的性能可以轻易的超于其它常见的非持久化消息引擎的性能。当然,t Q的非持久化消息的性能会表现的更好!
t Q完全使用,纯的设计让Q可以尽可能少的以来第三方的包。从设计模式来说,t Q这样的设计入侵性也最小。t Q既可以独立运行,也可以与其它应用程序服务器集成使用。
t Q拥有完善的错误处理机制,t Q提供服务器复制和故障自动转移功能,该功能可以消除消息丢失或多个重复信息导致服务器出错。
H t Q提供了灵活的集群功能,通过创建Q集群,您可以享受到到消息的负载均衡带来的性能提升。您也可以通过集群,组成一个全球性的消息网络。您也可以灵活的配置消息路由。
t Q拥有强大的管理功能。t Q提供了大量的管理A PI和监控服务器。它可以无缝的与应用程序服务器整合,并共同工作在一个环境中
e MQ和Q的比较:
特点t Q2.0GA e MQ5.3.0
客户端语言Java,Java,C#,C等1.1,jms1.2
应用协议
o n,XMPP,AMQP
支持的传送协议TCP,SSL,HTTP等-,JXTA等
监测消息支持支持
消息目标队列的分类使用e rts(排他和非排他)可
以使用过滤相匹配消息被转移
虚拟目标队列,镜像队列(队列自动复
制)和复合目的地队列
集群1.发布消息通过广播(UDP组播)
或固定客户端和服务端
2.支持负载均衡
3.消息的重分发:发送前,配置
无消费者对消息的重新分发的参
数。
4.容错机制(v er):主备服
务器(每一个主服务器只能有一
个冷备份服务器)
5.高可用性:异步日志复制从主
到备(快)或者通过共享文件系
1.发送消息通过广播(UDP组播或者零配
置)或者固定的客户端和服务端。
2.支持负载均衡
3.容错机制(v er):主备服务器
(每一个主服务器只有一个备服务器)
4.静态或者动态的发布。
5.针对消息的r的重分发。
6.高可用性:从主服务器异步日志到备份
服务器(快),或者通过D BC通过共享
文件系统存储(慢)或者共享存储(有没
有需要复制)
统的共享存储(有没有需要复
制)
JMX监控和管理支持,包含一个e b控制台支持
JMS到M S的i dge的方式支持,HQ到和HQ到任何
.1的服务器。一次只能提供一次,并保证在Q到
e s.
在集群中消息组和排他性消费。支持支持
性能(e)测试工具M S 压力测试r的性能测试
持久化仅支持异步日志系统
(a l),提供两种方式:
1.Java NIO
AIO(仅支持n ux2.6
以上的版本)
支持多种方式:
B(比较好的可扩展性,更短的恢
复时间。)
2.AMQ消息存储(快)
3.JDBC数据库(比较慢)
安全身份验证和授权的A S的配置文
件中定义。7中不同的权限。
JAAS的身份验证和配置文件授权。3中不
同的权限(读,写,管理)
Blob和消息的支持支持支持
调度传递(e ry)支持支持(使用)
消息转换(xml转换为对象)支持,但是仅仅在H Q和
e之间。
支持(其中i ng提供具体的实现方
案)
异步发送支持支持
e优化前置d ge 批量d ge,异步消息传递生产者流程控制支持(仅仅在n dow)支持(仅仅在n dow)
慢消费消息的处理支持支持
拦截器架构支持,在包一级传入的数据库捕
获
支持,使用一个拦截器栈捕获传入的消息
通配符的支持(a rd)支持支持
的支持不支持支持
重新传递策略延迟交还和D LQ DLQ,丢失的消息将无法在交付。消息优先级和权重的设置不支持支持
命令代理不支持支持在Q4.2以上
AMQP支持不支持支持
SOAP协议Web服务的支持不支持支持,使用c he Axis和C XF JEE应用服务整合支持,使用RA 支持,使用RA
超时消息的目标地址支持不支持
检查重复的消息支持不支持
集群中服务端的负载均衡支持支持
客户端负载均衡(e)支持(随机和循环)不支持
客户端容错机制v er) 支持,自动故障转移和应用管理
模式
支持,随机和循环使用故障转移协议
Vm传输支持支持
对Aja的支持未知支持
对n g的支持
t MQ
t MQ 是由t提供的一个AMQP 的开源实现,由以高性能、健壮以及y出名的g写成,因此也是继承了这些优点。
AMQP 里的两个主要组件:n ge 和,绿色的X 就是n ge ,红色的是,这两者都在r端,又称作r,这部分是t MQ 实现的,而蓝色的则是客户端,通常有c er 和m er 两种类型:
AMQP 有四个非常重要的概念:虚拟机a l host),交换机n ge),队列)和绑定(binding)。
?虚拟机: 通常是应用的外在边界,我们可以为不同的虚拟机分配访问权限。虚拟机可持有多个交换机、队列和绑定。
?交换机: 从连接通道e l)接收消息,并按照特定的路由规则发送给队列。
?队列: 消息最终的存储容器,直到消费客户端m er)将其取走。
?绑定: 也就是所谓的路由规则,告诉交换机将何种类型的消息发送到某个队列中。
通常的操作流程是:
?(1) 消费者: 创建信息通道。
?(2) 消费者: 定义消息队列。
?(3) 消费者: 定义特定类型的交换机。
?(4) 消费者: 设定绑定规则(包括交换机名称、队列名称以及路由键)。
?(5) 消费者: 等待消息。
?(6) 生产者: 创建消息。
?(7) 生产者: 将消息投递给信息通道(注明接收交换机名称和路由键)。
?(8) 交换机: 获取消息,依据交换机类型决定是否匹配路由规则(如需匹配,则对比消息路由键和绑定路由
键)。
?(9) 消费者: 获取并处理消息,发送反馈。
?(10) 结束: 关闭通道和连接。
队列定义参数:
?s ive: 仅创建者可以使用的私有队列,断开后自动删除。
?e: 当所有消费客户端连接断开后,是否自动删除队列。
交换机定义参数:
?type: 交换机类型,包括t和。
?e: 当所有绑定队列都不再使用时,是否自动删除该交换机。
如所定义队列和交换机已存在,a re 和e将直接使用,不会抛出异常。
交换机类型:
?t: 不处理路由键,将消息广播给绑定到该交换机的所有队列。
?t: 处理路由键,对消息路径进行全文匹配。消息路由键“ ” 只能匹配“ ” 绑定,不匹配“”这类绑定。
?:处理路由键,按模式匹配路由键。模式符号“#” 表示一个或多个单词,” ” 仅匹配一个单词。如“#” 可匹配“ ”,但“ ” 只匹配“ ”。
通过i ng配置来实现异步接收消息
类是用于发送消息的类。实现如下
Java代 码
1.g e t mq;
2.
3.t l ate;
4.
5.c{
6.t e l ate;
7.
8.c void e r i) {
9.g e = " + "#" + i;
10.n ge的名 称为", 的名称为e ue"
11.r S end(", e ue",
12.g e);
13.l n("发送第" + i + "个消息成功!内容为:"g e);
14.
15.t " + "#" + i;
16.r",
17.g es);
18.l n("发送第" + i + "个消息成功!内容为: g es);
19.}
20.
21.c void l ate) {
22.this.l ate;
23.}
24.
25.}
g的配置文件如下:-t mq.xml
Java代 码
1.o n="1.0"i ng="UTF-8"?>
2.="
3.:xsi="http://www.w-n ce"
4.t ion=
--3.0.xsd">
5. 6.=o ry"> 7.-=h ost" /> 8.r ty name=a me"=" /> 9.r ty name=o rd"=" /> 10.
11. 12.=n"> 13.r-arg ref=r y" /> 14.
15. 16.=t.core.l ate"> 17.r-arg ref=r y"r-arg> 18.
19.
21.r ty name=l ate">
23.r ty>
24.
25.>
对于发送消息的程序自己可以实现。
下面来看看接受消息的程序如下
e r类用于接收消息的处理类,如下
Java代 码
1.g e t mq;
2.
3.t java.util.Date;
4.
5.c Hell e r {
6.c void g text) {
7.l n(v ed: " + text);
8.
9.l n(new Date());
10.}
11.}
g的配置文件如下:-t mq.xml
Java代 码
1.
2.="
3.:xsi=-n ce"
4.t ion=http://www.spri
--3.0.xsd">
5.
6. 7.=o ry"> 8.r-=h ost" /> 9.r ty name=a me"=" /> 10.r ty name=o rd"=" /> 11.
12.
13. 14.=n"> 15.r-arg ref=r y" /> 16.
17.
18. 19.=t l ate"> 20.r-arg ref=r y"r-arg> 21.
22.
23.
25.r uc-="r-arg>
26.
27.
28. 29.=e r"> 30.
31.
32.
34.-="r-arg>
35.
36.
37.
38. 39.=a nge"> 40.-=t"r-arg> 41.
42.
43.
44.
46.-="0" ref="r-arg>
47.-="1" ref="r-arg>
48.-="2"=.#"r-arg>
49.
50.
51.
52. 53.=e r"> 54.
55.
56.
58.r-arg ref=e r" />
59.r ty name=d"=a ge"r ty>
60.r ty name=r" ref=r"r ty>
61.
62.
63. 64.=e wor"> 65.r ty name=N ame"="r ty> 66.r ty name=r y" ref=r y"r ty> 67.r ty name=" ref="r ty> 68.
69.
70.>
官网:/
和i tMQ,就好比i nx和e,s h和u id。简单、轻量级、高性能、易使用等特点,以及优先级、多队列、持久化、分布式容错、超时控制等特性。
设计思想
高性能离不开异步,异步离不开队列,而其内部都是-m er模式的原理。
应用
,一个高性能、轻量级的分布式内存队列系统,最初设计的目的是想通过后台异步执行耗时的任务来降低高容量b应用系统的页面访问延迟,支持过有.5 o n用户的s应用。后来开源,现在有k 大规模部署和使用,每天处理百万级任务。是典型的类c hed设计,协议和使用方式都是同样的风格。
核心概念
设计里面的核心概念:
?job
一个需要异步处理的任务,是d中的基本单元,需要放在一个中。
?tube
一个有名的任务队列,用来存储统一类型的o b,是u cer和m er操作的对象。
?c er
Job的生产者,通过命令来将一个job放到一个b e中。
?m er
Job的消费者,通过e命令来获取job或改变的状态。
Job生命周期
中一个b的生命周期如图2所示。一个有D四种状态。当u cer直接put一个job时,job就处于Y状态,等待来处理,如果选择延迟put,job就先到Y ED 状态,等待时间过后才迁移到状态。m er获取了当前A DY的o b后,该job的状态就迁移到R VED,这样其他的m er就不能再操作该j ob。当u mer完成该后,可以选择s e或者u ry 操作;e之后,job从系统消亡,之后不能再获取;s e操作可以重新把该j ob状态迁移回A DY(也可以延迟该状态迁移操作),使其他的e r可以继续获取和执行该;有意思的是b ury操作,可以把该o b休眠,等到需要的时候,再将休眠的kick回状态,也可以D状态的o b。正是有这些有趣的操作和状态,才可以基于此做出很多意思的应用,比如要实现一个循环队列,就可以将E D状态的job休眠掉,等没有A DY状态的job时再将I ED状态的job一次性k回D Y状态。
y cle:
e
--------------V ED] --------> *poof*
特性
?优先级
支持0到**32的优先级,值越小,优先级越高,默认优先级为。
?持久化
可以通过将job及其状态记录到文件里面,在d下次启动时可以通过读取l og来恢复之前的o b及状态。
?分布式容错
分布式设计和类似,各个v er之间并不知道彼此的存在,都是通过来实现分布式以及根据t ube名称去特定获取。
?超时控制
为了防止某个u mer长时间占用任务但不能处理的情况,为r ve操作设置了时间,如果该r不能在指定时间内完成job,job将被迁移回A DY状态,供其他r执行。
不足
没有提供删除一个b e的操作,只能将b e的b依次删除,并让k d来自动删除空b e。Tube是在被引用到时按需创建的。如果一个u be空了(也就是说不包含任何e d 或者i ed job)并且没有客户端引用,该将被删除。
不支持客户端认证机制(开发者将应用场景定位在局域网)。
t alk 协议
t alk协议是使用I I编码方式运行在p之上的。整个协议是由客户端主动发起p连接,发送命令和数据,等待响应,然后关闭连接来进行通信的。对于每一个连接,服务严格按照请求顺序处理每个请求,发送返回状态的时候也是相同的顺序。在协议中的所有整数都是十进制(除非特说说明)和非负的。
变量(或者是名字):在协议中,变量是C II字符串。可能包含字母(A-Z 和a-z),数字(0-9),字符(- + / ; . $ _ ( )).但是不能以-开始。以空格为结束符(可是是空格或者是回车还行符).每一个变量至少包含一个字母。
协议包含两种数据:命令行和非结构化的数据块。命令行用做客户端命令或者是服务端的响应。数据块用来传输任务体和状态信息。每一个任务体都是都是字节序列。服务不会审查和修改任务体,按照原始格式返回信息给客户端。是由客户端来决定任务体的实际意义。
当客户端不需要使用服务的时候,客户端将发出quit 命令或者是自动关闭C P连接。但是k d 可以胜任很大的k et并发连接,所以推荐客户端不要关闭连接,尽量的使用t连接通道。这样也避免了建立P连接的开销。
如果客户端违反了协议(例如:发送格式不对或者命令不存在)或者服务有问题,服务将返回下列错误信息中的一个:
1) "O RY\r\n" 服务没有足够的内存。客户端可以一会重试。
2) "R ROR\r\n" 服务有错误。应该永远不会发生,如果发生了,清在t alk-
talk.提交。
3) "\r\n" 客户端发送协议格式有问题。例如:命令行没有以\r\n结尾。命令行下一个变量不是期望中的
数字。错误的参数个数等等。
4) "\r\n" 客户端发送无效的命令。
以上的错误的返回值将会是所有命令的可能返回值,客户端在发送命令之后都要准备好接收错误响应。最后,如果服务端发生了严重的错误不能继续服务,服务端将会主动关闭连接。
c er 命令举例