0

当连接失败时,我们有一个自动连接的请求(这样消息就不会丢失/它的相关 ID 也不会丢失)。

通过连接到 IBM 6.x 远程 MQ 服务器的 IBM MQ 7x 客户端自动重新连接到消息/MQ 管理器(没有升级 7x MQ 服务器的选项)。

我试着做

如果 Manager 断开连接,则停止并重新连接

但这会不断丢失相关 ID 的值。

我正在使用 MQ.NET 类。另外,当出现连接故障时,请告知是否可以手动重新连接?

4

2 回答 2

2

为 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 从工作类中检索它,当 MQReceiveAction 成功重新连接时,将 CorrelID 推送到新的工作类中。

最好从 10,000 英尺的高度观察问题,并将其阻塞的组件分开。

于 2013-04-17T14:47:43.990 回答
2

将所有 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();
    }
于 2013-04-17T05:23:31.260 回答