消息中间件MQ入门

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MQ的基本概念:
首先了解什么是mq?mq的作用是什么?
mq是通讯中间件。

他的作用是省去开发人员开发通讯工具的时间,节省开发成本,提高开发效率。

如何安装mq?
根据以往的经验,win版的mq比较容易安装,傻瓜式,一路next就可以。

aix版本的用smitty安装。

linux版本用rpm -ivh 安装。

1) 队列管理器
队列管理器是MQ系统中最上层的一个概念,由它为我们提供基于队列的消息服务。

简单的说就是一个大容器的管理员,这个大容器里放了很多东西。

2) 消息
在MQ中,我们把应用程序交由MQ传输的数据定义为消息,我们可以定义消息的内容并对消息进行广义的理解,比如:用户的各种类型的数据文件,某个应用向其它应用发出的处理请求等都可以作为消息。

消息有两部分组成:
消息描述符(Message Discription或Message Header),描述消息的特征,如:消息的优先级、生命周期、消息Id等;
消息体(Message Body),即用户数据部分。

在MQ中,消息分为两种类型,非永久性(non-persistent)消息和永久性(persistent)消息,非永久性消息是存储在内存中的,它是为了提高性能而设计的,当系统掉电或MQ队列管理器重新启动时,将不可恢复。

当用户对消息的可靠性要求不高,而侧重系统的性能表现时,可以采用该种类型的消息,如:当发布股票信息时,由于股票信息是不断更新的,我们可能每若干秒就会发布一次,新的消息会不断覆盖旧的消
息。

永久性消息是存储在硬盘上,并且纪录数据日志的,它具有高可靠性,在网络和系统发生故障等情况下都能确保消息不丢、不重。

3) 队列
队列是消息的安全存放地,队列存储消息直到它被应用程序处理。

通俗的理解就是大容器里的东西,存放消息的盒子。

消息队列以下述方式工作:
a) 程序A形成对消息队列系统的调用,此调用告知消息队列系统,消息准备好了投向程序B;
b) 消息队列系统发送此消息到程序B驻留处的系统,并将它放到程序B的队列中;
c) 适当时间后,程序B从它的队列中读此消息,并处理此信息。

在MQ中,队列分为很多种类型,其中包括:本地队列、远程队列、模板队列、动态队列、别名队列等。

本地队列又分为普通本地队列和传输队列,普通本地队列是应用程序通过API对其进行读写操作的队列;传输队列可以理解为存储-转发队列,比如:我们将某个消息交给MQ系统发送到远程主机,而此时网络发生故障,MQ将把消息放在传输队列中暂存,当网络恢复时,再发往远端目的地。

远程队列是目的队列在本地的定义,它类似一个地址指针,指向远程主机上的某个目的队列,它仅仅是个定义,不真正占用磁盘存储空间。

模板队列和动态队列是MQ的一个特色,它的一个典型用途是用作系统的可扩展性考虑。

我们可以创建一个模板队列,当今后需要新增队列时,每打开一个模板队列,MQ便会自动生成一个动态队列,我们还可以指定该动态队列为临时队列或者是永久队列,若为临时队列我们可以在关闭它的同时将它删除,相反,若为永久队列,我们可以将它永久保留,为我所用。

4) 通道
通道是MQ系统中队列管理器之间传递消息的管道,它是建立在物理的网络连接之上的一个逻辑概念,也是MQ产品的精华。

通俗的理解就是大容器和大容器之间,程序和容器之间进行通讯的途径。

在MQ中,主要有三大类通道类型,即消息通道,MQI通道和Cluster通道。

消息通道是用于在MQ的服务器和服务器之间传输消息的,需要强调指出的是,该通道是单向的,它又有发送(sender), 接收(receive), 请求者(requestor), 服务者(server)等不同类型,供用户在不同情况下使用。

MQI通道是MQ Client和MQ Server之间通讯和传输消息用的,与消息通道不同,它的传输是双向的。

群集(Cluster)通道是位于同一个MQ 群集内部的队列管理器之间通讯使用的。

mq是如何实现通讯的?
mq的通讯方式有两种,通俗的说就是mq之间进行通讯,开发的程序和mq之间的通讯。

mq之间进行通讯:通过发送接收通道建立tcp连接进行消息传输,称为server对server
开发的程序和mq之间的通讯:通过服务器连接通道进行传输,client对server
MQ的工作原理
如图所示:
首先来看本地通讯的情况,应用程序A和应用程序B运行于同一系统A,它们之间可以借助消息队列技术进行彼此的通讯:应用程序A向队列1发送一条信息,而当应用程序B需要时就可以得到该信息。

其次是远程通讯的情况,如果信息传输的目标改为在系统B上的应用程序C,这种变化不会对应用程序A产生影响,应用程序A向队列2发送一条信息,系统A的MQ发现Q2所指向的目的队列实际上位于系统B,它将信息放到本地的一个特殊队列-传输队列(Transmission Queue)。

我们建立一条从系统A到系统B的消息通道,消息通道代理将从传输队列中读取消息,并传递这条信息到系统B,然后等待确认。

只有MQ接到系统B成功收到信息的确认之后,它才从传输队列中真正将该信息删除。

如果通讯线路不通,或系统B不在运行,信息会留在传输队列中,直到被成功地传送到目的地。

这是MQ最基本而最重要的技术--确保信息传输,并且是一次且仅一次(once-and-only-once)的传递。

MQ的基本配置举例
如何配置两台mq使之相互进行通讯?
首先要规划好两个队列管理器之间使用的ip和端口,假设我们使用
ip 端口
192.168.0.1 1414
192.168.0.2 1415
第一步建立队列管理器
crtmqm -lc -lf 100 -lp 3 -ls 3 QM1
解释下:
-lc 是采用循环日志
-lf 是每块日志的大小,4k为单位的,100就是100*4k
-lp 是主逻辑日志的数量
-ls 是辅逻辑日志的数量
QM1 是队列管理器名称
创建队列管理器时,应考虑的因素主要有:
1)队列管理器的日志类型以及日志文件的大小和个数,要根据用户数据量的大小、各个队列上的消息总容量,来计算日志的总容量,以免在系统运行过程中出现日志写满的情况;
2)应该为队列管理器指定和建立死信队列;
3)对最多打开句柄数MAXHANDS(缺省为256,如果您需要多于256个应用程序同时连接队列管理器,应增大该值),最大消息长度MAXMSGL,最多的未提交的消息个数MAXUMSGS 属性(缺省为10000,如果您使用了消息分段或分组,某个大消息的分段个数超过了10000,应增大该值)的考虑。

第二步启动队列管理器
1.要启动队列管理器,输入:strmqm
会有一条消息告诉您队列管理器已启动。

2.要启动 MQSC 命令,输入: runmqsc
当 MQSC 会话启动后会有一条消息告诉您。

MQSC 没有命令提示符。

第三步定义队列管理器中的队列和通道等
先运行runmqsc QM1首先要保证运行该命令的用户属于mqm组
运行完后进入mq命令窗口
3.定义本地队列 def ql(QL1)
先解释什么是本地队列,然后解释命令的含义(以下同)
本地队列是存储信息的盒子,用户可以从本地队列里取消息,对方发送消息的目的地也是本地队列。

def是 define的缩写,mq支持一些命令的缩写。

ql是queue local的缩写,表示本地队列,括号内是本地队列名
4.定义远程队列 def qr(QR1)
远程队列是相对于本地队列的,当用户希望往另一个队列管理器发消息的时候,配置好远程队列,用户直接放消息到该队列就可以,mq会传输到另一方的本地队列中。

以上面的例子说明,当我们把消息放入该远程队列后,消息会传输到QM2队列管理器中的QL2队列中。

qr queue remote的缩写
rname 指定的远程队列管理器上的队列名
rqname 远程队列管理器
xmitq 所要用的传输队列
5.定义传输队列 def ql(QT1)
定义传输队列 def ql(QT1) usage(xmitq) trigger trigtype(first) initq (system.channel.initq) trigdata(QM1.QM2)
传输队列是传输的介质,消息是通过传输队列进行传输的。

usage 用途xmitq是传输队列
trigger 消息触发开关
trigtype 触发类型第一条消息触发
initq 初始队列
trigdata 触发数据
对于队列的属性,应该考虑的因素主要有:
1)永久性和非永久性设置:尤其要注意的是DEFPSIST属性的缺省值为No,若要保证消息的安全可靠,必须将其设置为Yes;
2)对于本地队列和传输队列,要考虑队列的最大深度MAXDEPTH(缺省为5000,应根据实际情况计算该值),队列中每个消息的最大字节数MAXMSGL的配置。

6.定义发送通道 def chl(QM1.QM2)
定义发送通道 def chl(QM1.QM2) chltype(sdr) conname('192.168.0.2(1415)') trptype
(tcp) xmitq(QT1)
发送通道就相当于建立一个tcp的连接
chl channel的缩写
chltype 通道类型sdr是发送通道
conname 连接名包括对方的ip和端口
trptype 通讯类型tcp通讯
xmitq 使用的传输队列
7.定义接收通道 def chl(QM2.QM1)
定义接受通道 def chl(QM2.QM1)
接收通道是被动的,只定义名字就可以。

大家注意,接收通道的名字一定要和发送通道名一致,他们是靠名字来匹配。

对于通道的属性,应该考虑的因素主要有:
1)确定通道的运行方式采用长连接的方式还是触发的方式,通常,对于需要频繁启动的通道,不适宜采用触发的方式。

若采用触发方式启动通道,触发类型应为FIRST;
2)对于发送类型的通道,要考虑通道的断开间隔(DISCINT)、短重试次数(SHORTRTY)、短重试间隔(SHORTTMR)、长重试次数(LONGRTY)、长重试间隔(LONGTMR)、批处理大小(BATCHSZ)的配置。

8.要停止 MQSC,输入: end
将显示一些消息,后跟命令提示符。

第四步配置监听器
是对方mq管理器来探测,本地要给对方一个回应,监听器就是起这个作用的。

如果是5.3版本只能在命令行里运行 runmqlsr -m QM1 -t tcp -p 1414
如果是6.0版本可以runmqsc QM1里运行 def listener(LSR.QM1) trptype(tcp) port(1414) control(qmgr)
解释下 trptype 监听类型
port 监听端口
control 监听控制,如果是qmgr则在队列管理器启动的时候监听也自动启动。

启动监听器
START LISTENER(LSR.QM1)
第五步配置另外一个队列管理器
简单的说一下,和上面的差不多,只不过名字不一样。

大家自己尝试下:)
重新配置一个MQ可以执行runmqsc CCBDG < CCBDG.mq
MQ的API
上图揭示了IBM WebSphere MQ 编程的原理。

第一步是让应用程序与队列管理器连接。

它通过MQConnect 调用来进行此连接。

下一步使用MQOpen 调用为输出打开一个队列。

然后应用程序使用MQPut 调用将其数据放到队列上。

要接收数据,应用程序调用MQOpen 调用打开输入队列。

应用程序使用MQGet 调用从队列上接收数据。

在MQ的13个函数中,MQCONN/MQDISC是最耗CPU的两个函数,其次是MQOPEN和MQCLOSE这两个函数,因此要尽量避免必要地重复使用这几个函数。

比如,当您需要从队列中读取多条消息时,正确的编程方法应该如下
以C语言为例,一个MQ应用的开发流程如下:
MQCONN() /*建立与队列管理器的连接*/
MQOPEN() /*打开要进行读写操作的队列*/
MQPUT() /*将消息放入队列*/
MQGET() /*从队列中读取消息*/
MQINQ() /*查询队列的属性*/
MQSET() /*设置队列的属性*/
MQCLOSE() /*在读写等操作进行完之后,将队列关闭*/
MQDISC() /*断开与队列管理器的连接,释放相关的资源*/
即:连接/断开队列管理器一次,打开/关闭队列一次,读取消息多次。

而不应该反复建立与队列管理器的连接和反复进行队列打开/关闭操作。

相关文档
最新文档