IBM WebSphere MQ消息通道的配置和维护介绍

 
1. 概述

WebSphere MQ作为IBM软件家族的消息传输中间件产品,以其出色的特性和功能在业界享有盛誉。WebSphere MQ独特的安全机制、简便快速的编程风格、卓越不凡的稳定性、可扩展性和跨平台性,以及强大的消息通讯能力,使得它在银行、电信,还是在交通运输、政府机关等各行各业,赢得了很高的市场份额。在中国,WebSphere MQ同样拥有广泛的用户基础和许许多多的成功案例。它不仅具有跨平台、跨网络的特性,而且以其特有的先进机制保证对消息的"Once and Once only"的传输,做到不丢失、不复传。在WebSphere MQ给客户带来的众多价值中,有一点十分重要,就是它的通讯感知和恢复机制,尤其适用于我国目前的现状,在我国很多地方存在网络线路质量差,网络状态不稳定的现状。因为WebSphere MQ在支持同步通讯的同时,提供了基于消息队列存储-转发机制的异步通讯模式,应用程序只需将消息交给WebSphere MQ,就由WebSphere MQ负责将消息安全、可靠地发送出去,不再需要应用和人工的干预,当网络出现故障的情况下,或对方主机发生故障时,WebSphere MQ能够作到不需要人工干预,自动探测网络状况的好坏,并且在网络恢复正常之后能够继续正常工作,也即断点续传。

在WebSphere MQ的系统配置和维护中,通道(Channel)的配置和维护是较复杂也是最重要的部分,本文将对如何配置和维护WebSphere MQ消息通道进行介绍,并附录有关实现WebSphere MQ队列管理器双向通讯对象配置脚本。

 

2. 消息通道的配置 2.1 消息通道的类型

消息通道是把消息从一个队列管理器送到另一个队列管理器的通道。不要和MQI通道混淆,MQI通道是在MQ客户端和MQ服务器队列管理器之间发送消息的通道。我们这里讨论的是消息通道。WebSphere MQ中通信双方的消息通道类型有6种:

l  Sender

l  Receiver

l  Server

l  Requester

l  Cluster sender

l  Cluster receiver

 

上述消息通道类型配对共有5种:

l  Sender-receiver

l  Requester-server

l  Requester-sender(callback)

l  Server-receiver

l  Cluster sender-cluster receiver

下面分别对各种组合进行介绍,并给出配置脚本

2.1.1   Sender-receiver

Sender/Receiver通道是最常见的通道配置方式,Sender作为通道的发送方也是通道连接的主动发起方,Receiver作为通道的接收方也是通道连接的被动监听方。

 

在下面配置脚本中,通道连接两个队列管理器QM1和QM2。其中,QM1为Sender方,QM2为Receiver方。在QM1上配置了远程队列(QR2)和传输队列(TO.QM2),其中QR2指向队列管理器QM2上的本地队列(QL2),且QR2与TO.QMB2对应,即凡是要放入QR2队列的消息,在加上传输消息头后直接放入TO.QM2中等待发送。QM1上配置Sender通道(QM1.QM2)需要指定传输队列名以及对方的通信参数(IP地址和端口),通信参数必须与QM2上的侦听程序设置匹配。

Sender通道与传输队列TO.QM2对应,表示凡是在TO.QM2中等待发送的消息最终都可以由该通道送出。双方通道必须同名。

在连接通道的时候,我们只需在QM1端启动通道Start channel(QM1.QM2)。

2.1.2   Server-receiver

Server/Receiver与sender/Receiver类似。Server端是消息的发送方,也是连接的发起方。在配置的时候,必须指定对方的通信参数,由CONNAME设定。

 

2.1.3   Server-requester

Server/Requester通道也是一种较常见的通道配置方式,如图2所示。从消息流向来看,Server作为消息的发送方,requester作为消息的接收方。但是从连接方式来看,requester却是连接的主动方,server是被动方。这种模式常用于动态IP地址的环境中,Server是静态IP地址的服务器,Requester的机器上网后自动分配到一个IP地址,所以是动态的,由Requester发起连接后接收数据。

 

2.1.4   Sender-requester

Sender/Requester的连接过程稍微复杂一些,如图3所示。Requester首先与Sender连接,在通知对方连接参数后连接断开。Sender进行反向连接,消息也是反向传送的,即由Sender传给requester。这种反向连接的方式,称为回调连接(callback connection)。这种模式也常用于做双向验证,即双方必须都要知道对方的通信参数才能完成回调连接。

 

2.1.5   Cluster sender-cluster receiver

在一个cluster环境中,每一个队列管理器都一个Cluster sender通道,通过这个通道把消息发送到完全资源队列管理器,每一个队列管理器也有一个cluster-receiver通道可以用来接收cluster中的消息。

 

在本文中我们不重点介绍cluster sender-cluster receiver通道。

 

2.2 消息通道的触发机制 2.2.1   触发器原理

触发(Triggering),是一种自动启动应用程序的机制。

队列管理器把某种条件称为触发事件。如果队列被设置为触发类型,并且触发事件发生了,那么队列管理器将发送一个触发消息到一个称作启动队列的队列中。触发消息被放置到启动队列的过程意味着产生了触发事件。

处理队列管理器中的消息是触发监控程序(Trigger-Monitor Application),他的工作是读取触发消息并根据触发消息的信息做出相应的处理。触发监控程序没有什么特殊,它只不过是从启动队列读取消息的应用程序。

当队列管理器发现由一条消息到达被触发的队列之后,它产生的触发消息将被存放到启动队列中,触发监控程序将从启动队列中取出触发消息,并根据触发消息中的内容,启动相应的消息处理程序来处理被触发队列中的消息。

触发所涉及的对象如下所示:

1)        应用队列(Application Queue):一个本地队列并设置为可触发。当触发条件满足时,将会产生触发消息。

2)        传输队列:如果用触发方式来启动通道,则传输队列将对应了触发的应用队列。在传输队列的TriggerData属性中设置为将被启动的通道名,这将省略进程的定义。

3)        进程定义(Process Object):一个应用队列可能由一个进程定义对象和它关联。进程定义中包含应用程序的信息。该应用程序负责从应用队列中取出消息。

4)        触发事件:它是一种引起队列管理器产生触发消息的事件。

5)        触发消息:当触发事件发生时,队列管理器将产生触发消息。触发信息来自于应用队列和于应用队列关联的进程定义,它包含了将要被启动的程序名。

6)        启动队列:一个本地队列。被用来存发触发消息的队列。一个队列管理器可用拥有多个启动队列。一个启动队列可以为多个应用队列服务。

7)        触发监控器:是一个持续运行的程序,当一个触发消息到达启动队列时,触发监控器获取触发消息,并利用触发消息中的信息,启动应用程序来处理应用队列中的消息,并把触发消息头发送传递给应用程序,消息头中包含应用队列名。

 

在所有平台上,都有一个特殊的触发监控器叫做通道启动器(Channel Initator),它的作用就是启动通道。

2.2.2   触发类型

l  EVERY:

应用队列中每接受到一个消息时,都将产生触发消息。如果应用程序仅仅处理一个消息就结束,可采用这种触发类型。

l  FIRST:

应用队列中消息从0变为1时会触发事件。如果当队列中的一个消息到达时启动程序,直到处理完所有消息才结束,则采用这种触发类型。

l  DEPTH:

应用队列中消息数目和TriggerDepth(引起触发事件发生时,队列中的消息数目)属性值相同时,才会产生触发事件。当一系列请求的回复都收到时,才启动应用程序,则可以采用这种方法。

需要注意的时,当DEPTH属性值为0的时候,实际上就形成了同步通信。另外,当采用Depth触发时,产生触发消息以后,队列将被修改为非触发方式,如果需要再次触发,需要重新设置成允许触发。

  一般而言,在实际应用中,如果通道设置成触发方式,触发类型往往设置成为FIRST和DEPTH。

2.2.3   触发器工作流程

1)        本地或远程应用程序A,往应用队列(Application Queue)中PUT了一条消息。

2)        如果队列的触发类型设置为first,当队列原来深度为0时(队列为空),这时PUT一条消息到队列中将形成触发事件,同时产生一条触发消息,触发消息中将包含进程定义中的信息,因为进程定义中包含启动程序B所需的信息,所以触发消息中也包含了启动程序B所需的信息。

3)        队列管理器创建触发消息,并把它PUT入与应用队列相关的启动队列Initiation Queue。

4)        触发监控器(Trigger Monitor)从启动队列(Initiation Queue)中GET触发消息。

5)        触发监控器处理触发消息,发出启动应用程序B的命令。

6)        应用程序B打开应用队列(Application Queue),并处理队列中的消息。

 

注:如果是通道触发将可以不需要创建进程对象(process object),只是在传输队列的trigdata中设置需要启动的通道名。

 

2.2.4   配置消息通道触发

配置消息通道触发启动,需要使用到的对象有传输队列,通道启动队列,发送通道,通道启动器。我们本配置案例中传输队列名是QMB,通道启动队列采用SYSTEM.CHANNEL.INITQ,发送通道名QMA.QMB,通道启动器为runmqchi,该进程在队列管理器启动的时候自动启动。下面我们通过举例来演示配置实现消息通道触发启动。

l  首先我们来查看一下传输队列QMB都有哪些属性,显示如下清单所示,其中清单中的标注红色的属性和通道触发配置相关。

dis ql(QMB)

     1 : dis ql(QMB)

AMQ8409: 显示队列细节。

   QUEUE(QMB)                           TYPE(QLOCAL)

   ACCTQ(QMGR)                          ALTDATE(2009-02-06)

   ALTTIME(11.41.44)                       BOQNAME( )

   BOTHRESH(0)                           CLUSNL( )

   CLUSTER( )                             CLWLPRTY(0)

   CLWLRANK(0)                             CLWLUSEQ(QMGR)

   CRDATE(2008-12-05)                      CRTIME(10.37.53)

   CURDEPTH(0)                             DEFBIND(OPEN)

   DEFPRTY(0)                              DEFPSIST(NO)

   DEFSOPT(SHARED)                         DEFTYPE(PREDEFINED)

   DESCR( )                                DISTL(YES)

   GET(ENABLED)                            HARDENBO

   INITQ( )                                IPPROCS(1)

   MAXDEPTH(5000)                          MAXMSGL(4194304)

   MONQ(QMGR)                              MSGDLVSQ(PRIORITY)

   TRIGGER                                 NPMCLASS(NORMAL)

   OPPROCS(1)                              PROCESS( )

   PUT(ENABLED)                            QDEPTHHI(80)

   QDEPTHLO(20)                            QDPHIEV(DISABLED)

   QDPLOEV(DISABLED)                       QDPMAXEV(ENABLED)

   QSVCIEV(NONE)                           QSVCINT(999999999)

   RETINTVL(999999999)                     SCOPE(QMGR)

   SHARE                                   STATQ(QMGR)

   TRIGDATA( )                             TRIGDPTH(1)

   TRIGMPRI(0)                             TRIGTYPE(FIRST)

   USAGE(XMITQ)

 

l  设置传输队列为触发模式TRIGGER。

l  设置触发类型为every/first/depth其中的一种,例如TRIGTYPE(FIRST)。如果设置为TRIGTYPE(DEPTH),则还需要设置触发深度属性,例如TRIGDPTH(4),表示当队列中的消息数由3个增加到4个的时候才能形成触发事件,但需要注意的是深度触发事件只能产生一次事情,下次传输队列的消息数由3个增加到4个时候不会产生触发事件,所以在消息通道触发中,我们推荐采用TRIGTYPE(FIRST)。

l  在通道触发中,推荐使用SYSTEM.CHANNEL.INITQ队列作为初始队列, 该队列为MQ专用的通道启动队列, 不需要手工启动其触发监视器,设置传输队列INITQ(SYSTEM.CHANNEL.INITQ )属性。

l  通过TRIGDATA属性设置需要触发的通道名,例如TRIGDATA(QMA.QMB )。

l  对于TRIGMPRI属性的含义是基于消息优先级触发,也即某类优先级的消息满足的触发条件才产生触发事件,我们在消息通道触发中不推荐使用。

 

完整MQSC命令参考如下:

ALTER QL(QMB)  +

TRIGGER  +

TRIGTYPE(FIRST)  +

 INITQ(SYSTEM.CHANNEL.INITQ)  +

 TRIGDATA(QMA.QMB)

 

l  通道的触发监控器我们采用系统的自带的runmqchi程序,缺省队列管理器启动的时候,runmqchi进程会自动启动。

 

2.3 通道主要属性

消息通道的属性非常多,下面对一些重要属性进行介绍。

2.3.1   Channel type属性

通过的类型(CHLTYPE)有很多种,需要根据通道配对方式,设置您所需要的通道类型。请参看2.1小通道类型。

2.3.2   Connection name属性

作为消息通道,只有Sender,Server 和 Requester通道才使用Connection Name(CONNAME)属性。如果通讯协议是TCPIP,该属性设置可以指定通信对方的IP地址和端口号。

2.3.3   Transmission queue name属性

 

Transmission queue name(XMITQ) 属性是设置传输队列名,就是通道需要从这个队列取出消息然后发送到对方。sender 和server通道需要设置XMITQ属性。

 

2.3.4   Disconnect interval属性

Disconnect Interval(DISCINT)是发送和服务类型的通道所具有的一个参数,它的作用是:在它设置的时间间隔内,如果传输队列为空即通道上没有消息通过时,通道就会被停止。设置完Disconnect Interval参数之后,当发送方重起通道时,通道就会被正常启动。

Disconnect Interval的值会地影响通道的性能。如果把Disconnect Interval的值设置得非常小,会导致通道的频繁启动;反之,如果把Disconnect Interval的值设置得很大,则意味着即使通道上很长时间没有消息,系统资源也会被长期占用,从而影响系统的性能。因此,利用改变Disconnect Interval的值,我们可以有效地改善通道的性能。

当传输队列中没有消息要传送时, 发送方通道(SDR)、服务器通道(SVR)将在等待了该 参数指定的时间间隔后断开连接,停止通道。该参数以秒为单位,定义新的通道时,如果没有特别指定,该参数会继承系统对象的属性,设为6000秒,约两个小时。亦通道连续两个小时没有消息发送后就会停止。DISCINT参数设定为0,通道永远不会停止。

 

2.3.5   Heart Beat Interval属性

与Disconnect Interval(HBINT)相对应的是Heart Beat Interval这一参数(仅针对WebSphere MQ for AIX、HP-UX、OS/2、Sun Solaris、Windows NT/2000 V5.1以上)。它的作用是:在Heart Beat Interval指定的时间间隔内,如果传输队列上没有一直没有消息到达,发送方MCA会向接收方MCA发送一个心跳信号,据此给接收方通道以停止的机会,在这种情况下,它不必等待Disconnect Interval超时,也会将通道停止下来。同时,它会释放用来存贮大消息的内存空间并关闭接收方的队列。

为了使HeartBeat Interval和Disconnect Interval这两个参数更有效地发挥作用,一般情况下需要让Heart Beat Interval设置值小于Disconnect Interval设置值。

另外,如果我们使用的传输协议是TCP/IP,我们也可以利用设置TCP/IP的socket的SO_KEEPALIVE参数来实现这一功能。设置完SO_KEEPALIVE参数,并设置时间间隔之后,TCP/IP本身就会定期去检测另一端连接的状态,如果对方连接已断开,通道也会被停止。在这里,TCP/IP的时间间隔也应小于WebSphere MQ通道的Disconnect Interval的值。

2.3.6   ShortRetry和LongRetry属性

在发送类型等类型的通道属性中,还有四个参数是与通讯恢复和通道连接有关的,它们是:shortrty,shorttmr,longrty,longtmr,它们的缺省值分别是:10,60,999999999,1200,分别代表短重试时间间隔和次数以及长重试时间间隔和次数,它们的作用和含义在于当通道从running变为retrying状态时,按照这四个参数规定的时间间隔和次数进行通道重新连接的尝试,并且先进行短重试,短重试结束后,再进入长重试。

在设计这四个参数时,要注意以下两点:

1) 要确保短重试+长重试的时间〉故障恢复时间

例如:假设您估计您的系统故障恢复时间为1个小时,则要设置shorttmr*(time of shortrty)+longtmr*(time of shortrty)>2 hours这样,才能保证在故障恢复之后,通道仍然能够自动进行重新连接的尝试。

2) 重试间隔将影响自动恢复的效率

例如:如果您把短重试总时间设定为10分钟,而长重试时间间隔设为1小时,而网络在15分钟后,便已经恢复,可是此时,由于通道已经进入长重试阶段,它将在1个小时之后,才能通过长重试恢复通道的正常运行。相反,也不必把重试间隔设置得太短,应根据需要和用户的实际情况进行适中的设置。

 

2.3.7   Batch size属性

    通道的Batch size(BATCHSZ)值是影响通道性能的一个关键参数。在MQ进行消息传输时,通道对消息的处理也是在同步点的控制之下并具有交易特性的,在以下条件满足时,它将统一提交一批消息:

当发送的消息个数达到BATCHSZ时;或传输队列为空,并且在BATCHINT指定的时间间隔内一直没有消息到达时。

    缺省情况下,通道的Batchsz是50,这是一个较为合理和优化的设置。一个小的Batch size值会使每条消息占用大的资源。比如,假设我们在局域网的情况下,Batch size值越大,通道的性能越好。然而,在广域网环境下,要根据网络状况的好坏来设置该参数,若网络状况很差,Batch size值越大,可能会导致通道的性能越差。

2.3.8   NpmSpeed属性

       WebSphere MQ的消息分为永久性消息和非永久性消息两种,对于非永久性消息,通道属性NPMSPEED可以设置为FAST和NORMAL,为了提高性能,可以设定该属性为FAST。

2.4 通道通讯优化 2.4.1   选择侦听程序(Listener)的运行方式

 

MQ的侦听程序有两种配置和启动方式,一种是通过配置/etc/inetd.conf文件选择使用inetd方式, 也可以使用MQ自身提供的runmqlsr程序,所不同的是:runmqlsr 是一个线程应用,所以比inetd需要更少的内存消耗。因此,采用runmqlsr方式可以提高通道相关的性能。

 

2.4.2   选择通道的运行方式

    与侦听程序类似,与MQ通道对应的MCA代理程序也可以有线程和进程两种运行方式,可以通过定义通道的MCATYPE属性来设置通道MCA的运行方式为thread方式。让通道以线程方式运行而非进程方式运行,这样可以减少通道运行的进程个数和消耗的内存资源。

 

    对于以上两点,要注意的是:当通道的连接个数很多时,如在Unix平台上超过500个时,建议MCATYPE和listener采用进程的方式。

 

2.4.3   设置侦听程序的trusted运行方式

    与MQ应用程序类似,MQ的通道侦听程序也有trusted(fastpath)和non trusted(standard)两种运行方式,采用trusted运行方式可以降低CPU和内存消耗。将通道和侦听程序设置为trusted方式运行的方法是通过修改qm.ini配置文件中的MQIBindType参数来实现,即创建或修改qm.ini文件中与Channels相关的小节,例如:

 

Channels:

MQIBindType=FASTPATH 或者

MQIBindType=STANDARD

其中,FASTPATH表示trusted运行方式,而STANDARD表示非trusted运行方式。

2.4.4   通道的PipeLineLength属性

    从MQ版本V5.2开始,MQ提供了一个新的通道参数,即PipeLineLength属性,通过该属性,可以设置MCA采用多个线程的方式来传输消息,从而成为提高通道性能的又一个手段。缺省情况下,该参数数值为1,任何大于1的设置MQ本身都会将其设置为2。

    设置PipeLineLength的方法是修改qm.ini文件的Channels一节,如下:

Channels:

PipeLineLength=2

注意,必须在通道两端都进行设置,否则会自动取两者之间的最小值。

 

2.4.5   设置MaxChannels和MaxActiveChannels属性

 

    MaxChannels和MaxActiveChannels分别代表队列管理器允许配置的通道的最大个数和允许同时运行的通道的个数,MaxChannels的缺省值是100,MaxActiveChannels的缺省值与MaxChannels相同。如果您的并发通道连接个数超过了100,您需要修改这两个参数。这对于大并发的Client/Server间通讯尤为重要。

   

2.4.6   使用AdoptNewMCA

在WebSphere MQ的5.2版本以上,新增加了一个控制通道运行的新的参数,既AdoptNewMCA,它可以通过修改qm.ini文件的Channels一节进行修改,如:

 

Channels:

AdoptNewMCA=ALL

 

它可以被设置为:NO,SVR,SNDR,RCVR,CLUSRCVR,ALL,FASTPATH等值。当MQ接收到启动通道的请求,但是同时它发现与该通道对应的amqcrsta的进程已经存在,这时,该进程必须首先被停止,然后,通道才能启动。AdoptNewMCA的作用就是停止这种进程,并且为新的通道启动请求启动一个新的进程。

该属性可以将状态处于running状态的接收端通道强行终止,从而使发送端的通道启动或请求操作得以成功。

如果为某一通道指定了AdoptNewMCA的属性,但是新的通道由于"channel is already running"而启动失败,则它可以:

1) 新的通道通知之前的通道停止

2) 如果旧的通道在AdoptNewMCATimeout的时间间隔内没有接受该停止请求,相应的进程(或线程)被kill掉

3) 如果旧的通道经过步骤2仍未终止,则当第二个AdoptNewMCATimeout时间间隔到达时,MQ终止该通道,同时产生"channel in use"的错误。

 

2.4.7   实现断网续传和故障恢复

WebSphere MQ作为一个消息传输产品,本身是架构在TCP/IP之上的,因此与操作系统或网络底层的TCP/IP特性有着密切的关系,很多情况下我们要借助于修改操作系统的TCP/IP参数,来使它更好地为WebSphere MQ服务,从而更加完善地发挥WebSphere MQ的强大功能。

当我们要在WebSphere MQ的两个队列管理器之间建立通讯时,由于WebSphere MQ的通道是单向的,我们必须要建立两条通道(Chanel),比如建立两条类型分别为发送(sender)类型和接收(receiver)类型的通道来实现两个WebSphere MQ Server之间的通讯,在通道的两端WebSphere MQ利用MCA(消息通道代理)来管理和监控通道的启停等运行状态,并对通道两端的消息系列号(Message Sequence Number)等进行协同管理,以保证WebSphere MQ对消息的"Once and Once Only"的传输。对WebSphere MQ而言,在其系统配置配置文件mqs.ini文件中,在mqs.ini文件中,包含了对队列管理器的日志大小、通道属性以及通过XA标准与数据库协同工作时的有关参数的设置,除此之外,有一节用于控制有关TCP/IP特性的信息,即:

TCP:

KeepAlive=Yes或

KeepAlive=No

它的作用在于:当设置KeepAlive=Yes时,表示操作系统的TCP/IP参数设置对WebSphere MQ生效。

由于WebSphere MQ接收通道的MCA处于通讯的被动方,它一直等待从发送方传来的消息,因此它不知道什么时候发送方会停止发送消息,也不知道当网络出现故障时,发送方什么时候会从工作状态变为停止状态。这时由于出现网络故障,网络连接被断掉,发送方通道状态会由running状态变为retrying状态,发送方会试图重新建立网络连接,而这时接收方的通道却没有停下来,仍处于一种假"running"的状态,相应的我们会得到一个"Channel is in use"的错误信息,导致发送端想重起却重起不了。出现这一现象的原因是:当发送方MCA启动通道并长时间没有断开连接,这时出现网络故障,TCP/IP的socket连接被破坏,当发送停止通道并重新启动时,它需要建立一个新的socket连接,而接收方仍停留在原来的RECEIVE调用上,它的socket特征与发送方新的socket特征不一致,因此新的socket连接建立失败。

我们可以利用TCP/IP特性来克服这一点,更好地实现断网续传。通常,操作系统的TCP/IP参数的缺省设置是2个小时(常见的操作系统平台如:Windows 2000/NT以及AIX,HP-UX,Sun Solaris,Linux等,缺省设定均为2个小时)即发送KeepAlive探测包的时间是2小时,所以需要2个小时的时间它才会获知网络连接已经断开,这对于我们来说无疑是无法接受的。在这种情况下,我们可以通过配置TCP/IP KeepAlive参数来提高TCP/IP的响应速度,从而实现网络故障时WebSphere MQ能够迅速断开通道连接从而重新启动通道,实现断网续传的强大功能。只有这样,在发送端,MQ的channel才能由running状态变为retrying状态,同时,在接收端,MQ的channel才能由running状态变为not found状态, 这样,在网络或主机重新恢复时,通道才能重新建立起连接,恢复running状态。

要实现上述功能,我们需要作以下两方面的工作:

1)修改WebSphere MQ系统配置文件mqs.ini,增加如下一节:

TCP:

KeepAlive=Yes

 

目的是使系统的TCP/IP设置对WebSphere MQ生效。

2)修改操作系统的TCP/IP参数;

在不同的系统上,修改TCP/IP参数的方法略有不同,现仅以Windows 2000/NT、RISC6000和HP为例作一简单说明。

  • 在Windows NT平台上, 我们利用regedit来修改系统注册表,修改HKEY_LOCAL_MACHINE\CurrentControlSet\Services\Tcpip\Parameters下的以下三个参数:
    KeepAliveInterval,设置其值为1000
    KeepAliveTime,设置其值为300000(单位为毫秒,300000代表5分钟)
    TcpMaxDataRetransmissions,设置其值为5
  • 在RISC6000平台上, 用no命令修改如下参数:
    tcp_keepidle保持TCP/IP连接的时间,单位为0.5秒,缺省值为14,400,即两个小时,我们可将它设为5分钟;
    tcp_keepinittcp连接初始timeout值,单位为0.5秒,缺省值为150,我们可将它设为50;
    tcp_keepintvl连接间隔,单位为0.5秒,缺省值为150,我们可将它设为50;
    我们也可以修改/etc/rc.net文件,
    /usr/sbin/no -o tcp_keepidle=240
    /usr/sbin/no -o tcp_keepinit=50
    /usr/sbin/no -o tcp_keepintvl=50
    注意:直接使用命令行修改,在机器重启后,会失效;修改rc.net文件,可以做到永久生效。
  • 在HP平台上,
    对于HP-UNIX V10.20及其在此之前的版本,用/usr/contrib/bin nettune命令来修改有关参数;
    对于HP-UNIX V10.30及其以上版本,用/usr/bin/ndd命令来修改有关参数。
  • 在SUN Solaris平台上,
    用ndd -set /dev/tcptcp_keepalive_interval NNN命令来修改有关参数,tcp_keepalive_interval的单位为毫秒,缺省值为7200000毫秒,即2个小时。
  • 在SCO OpenServer平台上,
    tcp_keepalive 和 tcp_keepidle 相同,其原先默认值为 7200 秒,可设为 600秒。tcp_keepintvl 其原先默认值为 75 秒,可设为15秒。均以"秒"为单位。
    运行命令 ifconfig 命令修改:
    /etc/inconfig tcp_keepidle <value>
    /etc/inconfig tcp_keepintvl <value>
    需要注意的一点是通道两端的KeepAlive参数要保持协调一致,若发送端的KeepAlive值小于接收端的KeepAlive值,则当网络出现故障时,发送端的通道停下来之后,接收端的通道会仍然停不下来。
2.5 通道的维护

通过使用MQSC命令DEFINE来创建通道,DELETE删除通道。用DISPLAY显示通道属性,用ALTER修改属性。注意,通道只有在停止状态下才可以被删除或修改。

例如:

 

*创建接收端通道(QMA.QMB)

DEFINE CHANNEL(QMA.QMB) CHLTYPE(RCVR)

*创建发送方通道(QMA.QMB),连接对方的IP地址为192.168.1.100,端口为1415,通道连接传输队列TO.QMB

DEFINE CHANNEL(QMA.QMB) CHLTYPE(SDR) CONNAME(‘192.168.1.100(1415)’) XMTIQ(TO.QMB)

 

*删除通道(QMA.QMB)

DELETE CHANNEL(QMA.QMB)

*修改通道(QMA.QMB)的批次消息数量为100

ALTER CHANNEL(QMA.QMB) CHLTYPE(SDR) BATCHSZ(100)

*显示通道(QMA.QMB)的断开间隔时间

DISPLAY CHANNEL(QMA.QMB) DISCINT

*显示通道(QMA.QMB)的状态

DISPLAY CHS(QMA.QMB) AL

 

由于通道是一种特殊的MQ对象,它的某些状态会随着通信环境的改变而变化,比如通道状态、通道流量、通道消息序号等,我们称之为通道的动态信息。MQSC也提供了一些命令用来动态管理通道。

2.5.1   通道start命令

通道的启动可以通过MQSC的start channel命令完成,例如格式为:

START CHANNEL(ChannelName)

 

也可以在命令行通过runmqchl控制命令完成,两者效果相同,在Windows中还可以用MQ服务配置成自动启动方式。

runmqchl在通道连接的主动方使用,使用时需要指定队列管理器名和通道名。

$runmqchl [-m QMgrName] –c ChannelName

选项-m QMgrName表示队列管理器名,缺省为缺省队列管理器。–c ChannelName示通道.

例如:runmqchl –m QM1 –c QM1.QM2

 

在Websphere MQ for Windows产品中,可以通过WebSphre MQ服务(本地)工具来进行配置。

 

2.5.2   通道stop命令

用MQSC命令STOP CHANNEL可以停止通道,停止通道也只有在连接通道的主动方发起才有作用。例如格式为:

STOP CHANNEL(ChannelName)

 

2.5.3   通道reset命令

通道为传送的每一条消息分配了一个序列号,它会自动累计增值,每传送一条消息,双方的消息序号都会自动加一。这个消息序号在通道中用SEQNUM属性表示,在双方连接通道的时候会约定一个起始值,以后每传递一条消息各自加一。通道的相关属性SEQWRAP表示序号的最大值,缺省最大值为999,999,999。序列号越界后自动归零,从头开始。通道利用消息序号来标识传送和确认的消息。

通常情况下,通道双方的消息序号计数应该是相同的。然而在某些异常情况下,会出现双方序号不一致的情况,这通常是因为通信故障后,双方对前面的某一条(或一批)消息是否发送成功理解不一致。在解决了不确定(In-doubt)的消息后,可以用MQSC命令通过重置消息序号将双方调整到一致。一旦连接断开后,通道重连时双方MCA会将消息序号同步。如果通信异常造成序号不一致,可以在通道发送端用MQSC命令RESET CHANNEL SEQNUM手工将两者同步。

在连接通道的主动方重置消息序号会将双方一起调整,在被动方重置则只设置一端。

RESET CHANNEL(ChannelName) [SEQNUM(number)]

 

2.5.4   通道resolve命令

发送方和接收方的通道状态中除了SEQNUM(通道消息序号)参数控制消息传递外,还有LUWID参数。LUWID指的消息批次交易号,对于每一批消息发送方都需要收到接收方的确认信息才认为消息完整无误地送达对方,接着产生下一个LUWID并开始下一批消息传送。如果没有收到确认而与接收方失去联系,这时发送方认为这批消息为不确定(In-doubt)状态。

大多数时候,WebSphere MQ会在通道重连时自动解决不确定状态的问题。当然,我们也可以手工解决。事实上,通道的LUWID分成CURLUWID和LSTLUWID两个参数属性,具体工作过程如下:

l  发送方产生一个批次交易号,设置在CURLUWID并通知接收方

l  接收方将其设置在CURLUWID

l  发送方向接收方一条接一条地传送整批消息

l  接收方在完整地收到消息后,将交易号设置在LSTLUWID,提交整批消息并回送确认信息

l  发送方在接收确认信息后,将交易号设置在LSTLUWID,提交整批消息

l  重复上述步骤。

所以,在发送方出现不确定状态时,只需要比较一个发送方的CURLUWID和接收方的LSTLUWID,就可以知道该批消息在接收端是否已经提交,从而在发送方做出相应的动作即可。具体步骤如下:

1)比较双方的LUWID

●        对于不确定(In-doubt)状态的发送端:

DISPLAY CHSTATUS(ChannelName) SAVED CURLUWID

●        对于接收端:

DISPLAY CHSTATUS(ChannelName) SAVED LSTLUWID

2)如果两者相同,说明该批消息在接收端已经完整地收到并提交。在发送端执行:

RESOLVE CHANNEL(ChannelName) ACTION(COMMIT)

3)如果两者不同,说明该批消息在接收端未能完整地收到并提交。在发送端执行:

RESOLVE CHANNEL(ChannelName) ACTION(BACKOUT)

2.5.5   通道ping命令

类似于TCP/IP中的ping命令,MQSC命令中也有对通道的PING,格式如下。其中,DATALEN表示PING数据包的大小,可以用16字节到32,768字节。

PING CHANNEL(ChannelName) [DATALEN(16|integer)]

PING命令可以检查对方的队列管理器或端口监听器是否启动,也可以检查对方的通道定义是否正确。但不检查通道的通性状态。换句话说,PING CHANNEL只检查通道能否连通,而不检查目前是否连通。

3. 附录:MQ对象配置参考

队列管理器QMA和队列管理器QMB是互为双向通讯,它们都分别有本地接收队列,传输队列,死信队列,远程队列,发送通道,接收通道。

队列管理器QMA的对象定义清单:

*定义接收队列QLA

def ql(QLA) maxdepth(10000) defpsist(yes) maxmsgl(1048576)  replace

*定义传输队列TO.QMB

def ql(TO.QMB) usage(xmitq) defpsist(yes) maxdepth(10000) maxmsgl(1048576) +

   trigger trigtype(first) trigdata(QMA.QMB) initq(system.channel.initq) replace

                             

*定义发送通道QMA.QMB

def chl(QMA.QMB) CHLTYPE(SDR) discint(1800)  +

XMITQ(TO.QMB) CONNAME('11.193.9.74(1415)') trptype(tcp) +

shortrty(10000) shorttmr(30) longtmr(300) longrty(999999999) +

batchsz(50) replace

 

*定义接收通道QMA.QMB

def chl(QMB.QMA) CHLTYPE(RCVR) replace

 

*定义远程队列

def qr(QRB) rname(QLB) rqmname(QMB) xmitq(TO.QMB) defpsist(yes) replace

 

*定义死信队列

def ql(DEADQ) defpsist(yes) maxdepth(20000) replace

alter qmgr deadq(DEADQ)

*

alter ql(system.cics.initiation.queue) defpsist(yes)

 

*修改first触发间隔时间

alter qmgr trigint(5000)

 

 

队列管理器QMB的对象定义清单:

*定义接收队列QLB

def ql(QLB) maxdepth(10000) defpsist(yes) maxmsgl(1048576)  replace

*定义传输队列TO.QMA

def ql(TO.QMA) usage(xmitq) defpsist(yes) maxdepth(10000) maxmsgl(1048576) +

   trigger trigtype(first) trigdata(QMB.QMA) initq(system.channel.initq) replace

                             

*定义发送通道QMB.QMA

def chl(QMB.QMA) CHLTYPE(SDR) discint(1800)  +

XMITQ(TO.QMA) CONNAME('11.193.9.73(1415)') trptype(tcp) +

shortrty(10000) shorttmr(30) longtmr(300) longrty(999999999) +

batchsz(50) replace

 

*定义接收通道QMA.QMB

def chl(QMA.QMB) CHLTYPE(RCVR) replace

 

*定义远程队列

def qr(QRA) rname(QLA) rqmname(QMA) xmitq(TO.QMA) defpsist(yes) replace

 

*定义死信队列

def ql(DEADQ) defpsist(yes) maxdepth(20000) replace

alter qmgr deadq(DEADQ)

*

alter ql(system.cics.initiation.queue) defpsist(yes)

 

*修改first触发间隔时间

alter qmgr trigint(5000)

 

 

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页