消息队列是什么
消息队列对于我们来说应该并不陌生,消息队列(Message Queue,简称MQ),首先它是个队列,先进先出。队列里面放的是消息,消息则指的是两个独立的系统之间传递的数据,这两个系统可以是异构的,可以在不同的操作系统上,只需要写一段代码调用一下提供的API既可以发送或接收到消息。
为什么需要消息队列
这个问题的答案,我第一感觉就是解耦呗,两个系统之间抽离了一层出来用于处理消息传递,抽离出一层的好处是如果别的系统坏了也不会影响我这边系统的正常运行。解耦这算是一个,但还有一个原因可能更为重要,异步处理。在高并发场景中,往往同步处理容易导致阻塞,通过消息队列缓存消息,在某一时刻再去处理从而可以缓解系统压力。
(以上可能理解得有些粗糙…)
JMS规范
说到消息队列就不得不说JMS规范了。JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API。
JMS规范定义了两种消息通信模型:
1.Point-to-Point(P2P)点对点
2.Publish/Subscribe(Pub/Sub)发布订阅
在点对点模型中,消息生产者只需要将消息丢到消息队列中就可以了,一个消息只能有一个消费者,消费完之后消息就从队列中消失了。
发布订阅模型则涉及到一个主题(Topic)的概念,还有发布者(Publisher)和订阅者(Subscriber)。发布订阅模型允许一个消息可以有多个接收者。消息生产者产生一个消息后,把这个消息发送到一个Topic中,这个Topic可以同时有多个接收者在监听,当一个消息到达这个Topic之后,所有消息接收者都会收到这个消息。
目前市场上大多数的消息中间件都为JMS提供了实现。
消息队列的基本概念
以IBM WebSphere MQ为例,WebSphere MQ的结构图如图所示:
1) 消息
通过消息队列传输的数据我们都称它为消息。到了队列里面,消息分成了消息头(消息描述符)和消息体两部分,消息头存放了消息的优先级,失效时间等信息,而消息体放的是具体的用户数据(可能是字符串,可能是封装好的对象等等)。此外消息还可以分成持久性和非持久性两种。非持久性的消息存储在内存中,性能很好但可靠性不高断电就会消失,持久性的消息则被存储在硬盘中的,可靠性高,断电可恢复。
2) 队列
队列是存储消息的地方,采用先进先出的设计保证消息的一致性。在消息队列中队列分很多种,其中包括本地队列、远程队列、传输队列、别名队列等。本地队列就是我们平时调用API所操作的队列。远程队列是目的队列在本地的一个引用,真正的队列在远程主机上,因此远程队列不占用本地的存储空间。
本地队列
远程队列
3) 队列管理器
队列管理器可看成是队列和其他对象的容器。一个队列管理器是WebSphere MQ中的一个基本的独立的执行单元。一台机器上可以运行一个或多个队列管理器。队列管理器是MQ系统中最上层的一个概念,由它为我们提供基于队列的消息服务。
4) 通道
通道是消息队列中队列管理器之间传递消息的管道。
消息通道:消息通道是一种提供从一个队列管理器到另一个队列管理器的通信路径。主要用于在消息队列服务器和服务器之间传输消息的。消息通道是个单向连接,通过消息通道代理完成两个队列管理器的连接。
消息通道在WebSphere MQ中分成6种类型:
1.发送通道
2.接收通道
3.服务器通道
4.请求器通道
5.集群发送通道
6.集群接收通道
通道与通道之间要组合才能通信,通道组合共5种,分别是:
1.发送通道——接收通道
2.请求器通道——服务器通道
3.请求器通道——发送通道
4.服务器通道——接收通道
5.集群发送通道——集群接收通道
MQI通道:MQI通道是WebSphere MQ客户端和服务器上的队列管理器的通信的通道,当应用程序发出MQCONN或MQCONNX调用时,才开始建立连接。它是一个双向的通道,可以负责发送和接收。
MQI通道有两种类型:
1.客户端连接通道
WebSphere MQ客户端所使用。
2.服务器连接通道
运行队列管理器的服务器端所用,运行在客户端的应用程序使用这种通道进行通信。
基本概念性介绍大概就这些了吧。客户端应用程序具体用起来的话,使用WebSphere MQ Java API就可轻松连接上消息队列,配好MQEnvironment的一些参数,再new出MQQueueManager实例就可以调用队列发送消息了。具体怎么做我就不详细贴代码了。
在这里我要说明一些新手需要注意的几点:
1.用户记得加入mqm用户组。(2035报错)
2.记得启动队列管理器的监听端口(远程管理)。(2538报错)
3.创建的通道是服务器连接通道。
4.服务器连接通道的通道认证记录阻止用户里把星号去掉。(2035报错)