链接IBM MQ队列报MQRC_ALREADY_CONNECTED的问题说明

Vivienne ·
更新时间:2024-09-20
· 698 次阅读

链接IBM MQ队列报MQRC_ALREADY_CONNECTED的问题说明

因项目使用到IBM MQ与其他服务器交换数据,在测试过程中,发现一直存在队列报错问题,大致报错内容如下:

Traceback (most recent call last): MQError: MQRC_ALREADY_CONNECTED

后在多人帮助下发现,可能由于在于MQ交互过程的逻辑使得此问题的出现:

交互逻辑中,所使用到的是tornado框架下的ioloop定时器,已每20秒异步触发一次函数的方式去链接一次MQ: if __name__ == "__main__": init_log() app = make_app() app.listen(9900, "127.0.0.1") tornado.ioloop.PeriodicCallback(doTask, 1000 * 20).start() tornado.ioloop.PeriodicCallback(doCompress, 1000 * 60 * 60 * 2).start() tornado.ioloop.IOLoop.current().start() 链接MQ的逻辑为:
根据交互创建与MQ指定队列的链接 ----> 将消息从MQ取出/把消息放到MQ队列中 ----> 断开与MQ的链接 ----> 开启下一个交互 ----> 根据交互创建与MQ指定队列的链接
以此循环,直至本次所有的交互全部结束;
原先使用的链接的代码源自pymqi使用手册中,内容如下: import pymqi queue_manager = 'QM1' channel = 'DEV.APP.SVRCONN' host = '127.0.0.1' port = '1414' queue_name = 'TEST.1' message = 'Hello from Python!' conn_info = '%s(%s)' % (host, port) qmgr = pymqi.QueueManager(None) qmgr.connect_tcp_client(queue_manager, pymqi.CD(), channel, conn_info) try: qmgr.connect_tcp_client(queue_manager, pymqi.CD(), channel, conn_info) except pymqi.MQMIError as e: if e.comp == pymqi.CMQC.MQCC_WARNING and e.reason == pymqi.CMQC.MQRC_ALREADY_CONNECTED: # Move along, nothing to see here.. pass queue = pymqi.Queue(qmgr, queue_name) queue.put(message) queue.close() qmgr.disconnect() [上述代码源于pymqi手册,链接如下](https://dsuch.github.io/pymqi/examples.html#how-to-avoid-mqrc-already-connected) 故,在第一次链接时,可能由于MQ中并无消息,这将导致链接后,反馈的MQ队列无消息错误: Traceback (most recent call last): pymqi。MQMIError:MQI Error,Comp:2,Reason 2033:MQRC_NO_AVAILABLE 此导致,链接过程的最后两步(断开队列,断开链接)并未执行,而直接跳转到下次链接过程

此处,在多人的帮助下,将手册中的代码改动后,目前验证情况下,并未再次发生链接时报错,MQ已经链接问题,具体改动内容看代码:

def connect(): recv_mq = { "ip": "10.232.129.54", "port": "1416", "username": "mqm", "password": "mqm", "recv_queue_manager": "VMFSMESMQTEST1", "recv_channel": "CLI.PD.MES.MEB.1" } host = recv_mq["ip"] + "(" + recv_mq["port"] + ")" global qmgr qmgr = pymqi.QueueManager(None) # qmgr.connect_tcp_client(recv_mq["recv_queue_manager"], pymqi.CD(), recv_mq["recv_channel"], host, # recv_mq["username"], recv_mq["password"]) try: qmgr.connect_tcp_client(recv_mq["recv_queue_manager"], pymqi.CD(), recv_mq["recv_channel"], host,recv_mq["username"], recv_mq["password"]) except pymqi.MQMIError as e: print("Connect to MQ Error:",e) if e.comp == pymqi.CMQC.MQCC_WARNING and e.reason == pymqi.CMQC.MQRC_ALREADY_CONNECTED: pass def connectmq_put(recv_mq, str1): queue = pymqi.Queue(qmgr, recv_mq["recv_queue"]) queue.put(str1) queue.close() #qmgr.disconnect() def connectmq_get(recv_mq): queue = pymqi.Queue(qmgr, recv_mq["recv_queue"]) str1 = queue.get() queue.close() #qmgr.disconnect() return str1

将完整的循环逻辑拆分,定时器触发异步执行时,直接链接MQ服务器,并将链接引为全局,每次与MQ交互只链接队列,执行connectmq_put或者connectmq_get即可,待本次异步过程结束,使用先前声明的全局变量将链接断开即可:

qmgr.disconnect()

学习不易,身在其中,深有感悟!希望可以帮到大家


作者:gqf960708



mq ibm

需要 登录 后方可回复, 如果你还没有账号请 注册新账号