【问题标题】:Connecting back automatically when there is a loss of connection断开连接时自动重新连接
【发布时间】:2014-11-12 22:07:56
【问题描述】:

我们请求在连接失败时自动连接(这样消息就不会丢失/相关 ID 也不会丢失)。

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

我试过了

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

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

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

【问题讨论】:

    标签: c# .net ibm-mq


    【解决方案1】:

    最好将所有 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();
        }
    

    【讨论】:

      【解决方案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 英尺的高度看问题,并将其阻塞的组件分开。

      【讨论】:

        猜你喜欢
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-02
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多