为MQ应用程序创建重新连接逻辑非常简单。我喜欢有一个控制器类和一个工人类来处理重新连接逻辑。去看看Universal File Mover(UFM), http://www.capitalware.biz/ufm_overview.html 特别是MQReceive Action。是的,UFM是用Java编写的,但Java / MQ代码和C#/ MQ代码之间也没有区别。 UFM是一个开源项目,源代码可供下载。
特别是,请查看MQReceiveAction.java和MQGetMsg.java类。 MQReceiveAction.java是控制器类,MQGetMsg.java是工作类。 MQReceiveAction通过MQGetMsg类连接到队列管理器。发生MQException时,MQReceiveAction将通过MQGetMsg与队列管理器断开连接并休眠1分钟,然后尝试重新连接到队列管理器。
但这会不断失去相关ID的价值。
那么,你把它保存在一个没有被丢弃/清理的课程中吗?在我的示例中,如果我需要临时保存CorrelID,我只需让MQReceiveAction从worker类中检索它,并且当MQReceiveAction成功重新连接时,将CorrelID推送到新的worker类中。
最好从10,000英尺处查看问题并将其分开的组件分开。
将所有MQ方法调用放在try / catch块和catch块中总是好的,确定异常是否是连接错误,然后重新连接并重新打开之前打开的所有MQ对象。例如:
public static void GetQueueName() { Hashtable mqProps = new Hashtable(); MQQueueManager qm = null; String strCorrelId = "00123456789"; MQQueue importQ = null; Reconnect: try { mqProps.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED); mqProps.Add(MQC.CHANNEL_PROPERTY, "NET.CHL"); mqProps.Add(MQC.HOST_NAME_PROPERTY, "localhost"); mqProps.Add(MQC.PORT_PROPERTY, 2099); qm = new MQQueueManager("QM1", mqProps); } catch (MQException mqex) { // Handle any exception appropriately } try { importQ = qm.AccessQueue("Q1", MQC.MQOO_INPUT_SHARED | MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING); MQMessage mqPutMsg = new MQMessage(); mqPutMsg.WriteString("This is an import message"); mqPutMsg.CorrelationId = System.Text.Encoding.UTF8.GetBytes(strCorrelId); MQPutMessageOptions mqpmo = new MQPutMessageOptions(); mqpmo.Options = MQC.MQPMO_NEW_CORREL_ID; importQ.Put(mqPutMsg,mqpmo); MQMessage respMsg = new MQMessage(); MQGetMessageOptions gmo = new MQGetMessageOptions(); gmo.WaitInterval = 3000; gmo.Options = MQC.MQGMO_WAIT; importQ.Get(respMsg, gmo); } catch (MQException ex) { switch(ex.ReasonCode) { case MQC.MQRC_CONNECTION_BROKEN: case MQC.MQRC_CONNECTION_ERROR: case MQC.MQRC_CONNECTION_QUIESCING: { try { importQ.Close(); qm.Disconnect(); } catch (Exception ex1) { // Ignore any exception } goto Reconnect; } } } importQ.Close(); qm.Disconnect(); }