ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » General IBM MQ Support » MQ client auto reconnect

Post new topic  Reply to topic
 MQ client auto reconnect « View previous topic :: View next topic » 
Author Message
felfel
PostPosted: Tue Jul 15, 2008 1:40 am    Post subject: MQ client auto reconnect Reply with quote

Apprentice

Joined: 02 Nov 2004
Posts: 26

Hi ,


Does anybody have a sample code on how to manage a client auto reconnection to a remote queue manager ?
Java or MQI is ok.
I just want to see how to manage it in any application code.

Thanks for your help,
_________________
"Mens sana in corpore sano"
Back to top
View user's profile Send private message
bruce2359
PostPosted: Tue Jul 15, 2008 6:49 am    Post subject: Reply with quote

Poobah

Joined: 05 Jan 2008
Posts: 9469
Location: US: west coast, almost. Otherwise, enroute.

Not sure I understand what you are asking. An MQ client application use of every MQI call drives the connection to the svrconn channel at the qmgr.
_________________
I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live.
Back to top
View user's profile Send private message
omhopper
PostPosted: Tue Jul 15, 2008 6:54 am    Post subject: MQ client auto reconnect Reply with quote

Novice

Joined: 08 Jun 2007
Posts: 17

This is the catch block for a SIMPLE java message reader I wrote as a way to show someone how to re-establish a connection when it get's broken. It would probably be best to check for specific errors so that you can be sure that it is safe to try to recover from them.

I catch any JMSException, then wait 15 seconds and restart the connection.

catch (JMSException je) {
System.err.println("JMSException: "+je);
Exception e = je.getLinkedException();
if (e != null) {
System.err.println("linked exception: "+e);
}

e.printStackTrace();
Thread.sleep(15000);

System.out.println(" ");
System.out.println("Attempting to reconnect ... ");
System.out.println(" ");

qConn = qConnFactory.createQueueConnection();
qConn.start();

qSession = qConn.createQueueSession ( transacted, qSession.AUTO_ACKNOWLEDGE);

queueReader = qSession.createReceiver(ioQueue);
continue;
}
_________________
Thanks.
Back to top
View user's profile Send private message
zpat
PostPosted: Tue Jul 15, 2008 7:34 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5866
Location: UK

You want to retry the MQCONN in 30 seconds if you get MQRC 2059 on the connect or if you get MQRC 2009 on other MQI calls.

Retry the MQGET or MQPUT after 30 seconds if you get 2016, 2051 (queue inhibited).

Have a think about handling 2080, 2079, 2119, 2110 and dealing with poison messages. If using syncpoint, inspect the backout count to avoid a loop on MQGET.

Some MQRCs need intervention and may not be worth retrying for including 2035, 2058, 2161, 2162.

Make sure you log the MQRC (other than 2033) for support purposes.
Back to top
View user's profile Send private message
PeterPotkay
PostPosted: Tue Jul 15, 2008 1:47 pm    Post subject: Reply with quote

Poobah

Joined: 15 May 2001
Posts: 7722

Here is some code from an app I wrote in VB.NET. Take it for what its worth - just some code posted by a stranger on the internet. Use it as a sample but make sure you test, test, test. I wrote it to learn VB.NET. Its not a production app.

Code:

Sample MQ Code
Below is MQ code from a sample MQClient application that hovers on a queue, waiting for a message to arrive. The code follows all of the above principles, particularly the reconnect logic. The programming language is VB.NET.
Private Sub Reconnector()        '**********************************************************************************************
        ' Reconnector encompasses all the code that interacts with MQ
        ' and reads/updates the fields on the form
        '**********************************************************************************************
        EndOfLoop = False
        EndOfGETLoop = False
        thereIsAQueueOpen = False
        thereIsAQueueManagerConnected = False
        retryCounter = 0
        PrintToScreen("Application starting....", True)

        '**********************************************************************************************
        '   Creat a new empty Hash Table to house all the connection info needed
        '   by our MQClient, and then populate all the fields in that Hash Table.
        '   The below example populates all the fields from the GUI screen. Typically, these values
        '   would be populated from an ini or config file of some sort.
        '
        '   This application tries to connect to the same Queue Manager on the same server
        '   over and over. If you wanted to try alternate Queue Managers / Servers, the building
        '   of the Hash table should be moved inside the loop.
        '   Using some sort of interal flag/counter, you would then attempt connections to the alternate
        '   QM(s) after x failed attempts to the primary. Don't give up on the primary too quick, as your
        '   failed connection may be a result of a network blip, and there is no reason to abandon the
        '   primary QM.
        '
        '   If your app sits on a queue and waits for incoming messages, make sure the
        '   sending apps will be able to get their request messages to your alternate QMs. Apps that
        '   connect, put a request, await the reply, and then disconnect do not have this concern, as
        '   the request message will contain the connected QM name in the MQMD_ReplyToQM always, and
        '   so replying app can send the reply message to the correct QM.
        '*********************************************************************************************
        Dim myHashTable As New Hashtable
        myHashTable.Add(IBM.WMQ.MQC.CHANNEL_PROPERTY, ComboBoxClientChannel.Text)
        myHashTable.Add(IBM.WMQ.MQC.HOST_NAME_PROPERTY, ComboBoxHostname.Text)
        myHashTable.Add(IBM.WMQ.MQC.PORT_PROPERTY, ComboBoxPortNumber.Text)
        'myHashTable.Add(IBM.WMQ.MQC.SSL_CIPHER_SPEC_PROPERTY, ComboBoxSSLCipherSpec)
        'myHashTable.Add(IBM.WMQ.MQC.SSL_PEER_NAME_PROPERTY, ComboBoxSSLPeerName)
        'myHashTable.Add(IBM.WMQ.MQC.SSL_CERT_STORE_PROPERTY, ComboBoxSSLKeyRepository)
        myHashTable.Add(IBM.WMQ.MQC.SECURITY_EXIT_PROPERTY, ComboBoxSecurityExit.Text)

        Do
            Try
                '**********************************************************************************************
                '    This section determines how quickly we try to reconnect
                '    Try the 1st 5 times 1 second apart
                '        the 2nd 5 times 2 seconds apart
                '        the 3rd 5 times 5 seconds apart
                '        the 4th 5 times 10 seconds apart
                '        every 60 seconds forever after that
                '**********************************************************************************************
                If retryCounter > 20 Then
                    sleepInterval = 60000
                Else
                    If retryCounter > 15 Then
                        sleepInterval = 10000
                    Else
                        If retryCounter > 10 Then
                            sleepInterval = 5000
                        Else
                            If retryCounter > 5 Then
                                sleepInterval = 2000
                            Else
                                sleepInterval = 1000
                            End If
                        End If
                    End If
                End If

                '**************************************************
                '    Connect to the Queue Manager
                '**************************************************
                If retryCounter > 0 Then
                    PrintToScreen("Waiting " & sleepInterval & " milliseconds before trying to reconnect.", False)
                    System.Threading.Thread.Sleep(sleepInterval)
                End If
                LastMQCall = "MQCONNX"
                'note that MQClients never need to specify the QM Name. At The Hartford, they never should!
                'The(port#/Hostname) combo is specific enough to ID the QM for clients
                myQM = New MQQueueManager(ComboBoxQMName.Text, myHashTable)
                thereIsAQueueManagerConnected = True
                retryCounter = 0
                EndOfGETLoop = False

                PrintToScreen("Connection succesfully made to " & myQM.Name, False)
                PrintToScreen(LastMQCall & "....RC=0000", True)

                '**************************************************
                '    Open the Queue
                '**************************************************
                LastMQCall = "MQOPEN"
                openOptions = 0
                openOptions = openOptions + MQC.MQOO_INPUT_SHARED _
                                          + MQC.MQOO_INQUIRE _
                                          + MQC.MQOO_FAIL_IF_QUIESCING
                myQ = myQM.AccessQueue(ComboBoxQueueName.Text, openOptions)
                thereIsAQueueOpen = True
               
                PrintToScreen("Succesfully opened " & myQ.Name, False)
                PrintToScreen(LastMQCall & "....RC=0000", True)
                '*******************************************
                '   First, prepare to make the MQGETs
                '*******************************************
                gmo = New MQGetMessageOptions
                gmo.Options = 0
                gmo.Options = gmo.Options + MQC.MQGMO_WAIT _
                                          + MQC.MQGMO_SYNCPOINT _
                                          + MQC.MQGMO_ACCEPT_TRUNCATED_MSG _
                                          + MQC.MQGMO_FAIL_IF_QUIESCING
                gmo.WaitInterval = TextBoxWaitInterval.Text
                myMsg = New MQMessage 'create a buffer to hold the incoming message
                LastMQCall = "MQGET"
                Do 'Until EndOfGETLoop
                    '**************************************************
                    '    Start issuing MQGETs in a loop
                    '**************************************************
                    Try
                        With myMsg
                            .MessageId = MQC.MQMI_NONE
                            .CorrelationId = MQC.MQCI_NONE
                            .ClearMessage()
                        End With
                        PrintToScreen(LastMQCall & " issued with a " & gmo.WaitInterval & " wait interval.", True)
                        myQ.Get(myMsg, gmo)
                        myQM.Commit()
                        myMsgTxt = myMsg.ReadString(40)

                        '***********************************************************************************
                        '   print a good return message to the log, and then display 40 bytes of the message
                        '***********************************************************************************
                        PrintToScreen("MQ Message= '" & myMsgTxt & "'", False)
                        PrintToScreen(LastMQCall & "....RC=0000", True)

                        '**********************************************************************************
                        'logic to check for a MQFB_QUIT message here, to drop out of both loops.
                        '**********************************************************************************
                        If myMsg.Feedback = MQC.MQFB_QUIT Then
                            EndOfLoop = True
                            EndOfGETLoop = True
                            PrintToScreen("Quit message received. Ending now.", True)
                        End If

                        '**********************************************************************************
                        'Logic to check for a Backout Count greater than X.
                        'Really only applicable for apps that are triggered and do MQGETs with SYNCPOINT
                        'Can be used for non triggered apps that do MQGets with SYNCPOINT also
                        'It prevents a poisoned message loop, which can be explained as follows:
                        '    1.App is triggered
                        '    2.App Gets the message under syncpoint
                        '    3.Condition XYZ causes the app to end abnormally, and thus the messages is
                        '      rolled back onto the queue. The MQMD_Backout_Count is upped by 1.
                        '    4.App is instantly retriggered
                        '    5.Repeat steps 1 to 4 forever.
                        '**********************************************************************************
                        If myMsg.BackoutCount > 2 Then
                            '........or > whatever # makes sense for you
                            '........or > myQ.BackoutThreshold()
                            'Now handle the bad message!
                            'Maybe move the message to a predefined Exception Queue.
                            'Maybe move the message to myQ.BackoutRequeueName.
                            'Maybe there is nothing wrong with the message, and your app
                            'just needs to stop (what if a needed DB is down?). Call MQSupport
                            'to stop triggering in this case.
                        End If



                        '**************************************************
                        '   This is where an application’s business logic
                        '   that dealt with the message would go
                        '**************************************************
                    Catch mqError As MQException
                        Select Case mqError.ReasonCode
                            Case MQC.MQRC_NO_MSG_AVAILABLE
                                ListBoxMQICall.Items.Insert(0, "No message available on the queue.")
                            Case MQC.MQRC_TRUNCATED_MSG_ACCEPTED
                                ListBoxMQICall.Items.Insert(0, "Truncated message accepted.")
                                ListBoxMQICall.Items.Insert(0, "MQ Message= '" & myMsgTxt & "'")
                                myQM.Commit()
                            Case MQC.MQRC_NOT_CONVERTED
                                ListBoxMQICall.Items.Insert(0, "Unconverted message returned.")
                                ListBoxMQICall.Items.Insert(0, "MQ Message= '" & myMsgTxt & "'")
                                myQM.Commit()
                            Case MQC.MQRC_FORMAT_ERROR
                                ListBoxMQICall.Items.Insert(0, "Unconverted message returned.")
                                ListBoxMQICall.Items.Insert(0, "MQ Message= '" & myMsgTxt & "'")
                                myQM.Commit()
                            Case MQC.MQRC_CONVERTED_MSG_TOO_BIG
                                ListBoxMQICall.Items.Insert(0, "Unconverted message returned.")
                                ListBoxMQICall.Items.Insert(0, "MQ Message= '" & myMsgTxt & "'")
                                myQM.Commit()
                            Case MQC.MQRC_CONVERTED_STRING_TOO_BIG
                                ListBoxMQICall.Items.Insert(0, "Unconverted message returned.")
                                ListBoxMQICall.Items.Insert(0, "MQ Message= '" & myMsgTxt & "'")
                                myQM.Commit()
                            Case MQC.MQRC_Q_MGR_NOT_AVAILABLE
                                'Its OK not to end the main loop. This is possibly a temporary error condition.
                                EndOfGETLoop = True
                            Case MQC.MQRC_Q_MGR_QUIESCING
                                'Its OK not to end the main loop. This is possibly a temporary error condition.
                                EndOfGETLoop = True
                            Case MQC.MQRC_Q_MGR_STOPPING
                                'Its OK not to end the main loop. This is possibly a temporary error condition.
                                EndOfGETLoop = True
                            Case MQC.MQRC_CONNECTION_BROKEN
                                'Its OK not to end the main loop. This is possibly a temporary error condition.
                                EndOfGETLoop = True
                            Case MQC.MQRC_CONNECTION_QUIESCING
                                'Its OK not to end the main loop. This is possibly a temporary error condition.
                                EndOfGETLoop = True
                            Case MQC.MQRC_CONNECTION_STOPPING
                                'Its OK not to end the main loop. This is possibly a temporary error condition.
                                EndOfGETLoop = True
                            Case MQC.MQRC_OBJECT_CHANGED
                                'Its OK not to end the main loop. This just means something changed in
                                'the queue definition. Reopen the queue to pick up the change, and keep going
                                'This will probably never be returned for an MQGET, but definitly could
                                'be returned on an MQPUT to a Remote Queue Definition.
                                EndOfGETLoop = True
                            Case Else
                                EndOfGETLoop = True
                                EndOfLoop = True
                        End Select
                        PrintToScreen(LastMQCall & "...." & mqError.Message, False)
                        PrintToScreen(LastMQCall & "....RC=" & mqError.Reason, True)
                    End Try
                Loop Until EndOfGETLoop
            Catch mqError As MQException
                thereIsAQueueOpen = False 'assume we have lost our connection
                thereIsAQueueManagerConnected = False
                Select Case mqError.ReasonCode
                    Case MQC.MQRC_Q_MGR_NOT_AVAILABLE
                        'Its OK not to end the loop. This is possibly a temporary error condition.
                    Case MQC.MQRC_Q_MGR_QUIESCING
                        'Its OK not to end the loop. This is possibly a temporary error condition.
                    Case MQC.MQRC_Q_MGR_STOPPING
                        'Its OK not to end the loop. This is possibly a temporary error condition.
                    Case MQC.MQRC_CONNECTION_QUIESCING
                        'Its OK not to end the main loop. This is possibly a temporary error condition.
                    Case MQC.MQRC_CONNECTION_STOPPING
                        'Its OK not to end the main loop. This is possibly a temporary error condition.
                    Case MQC.MQRC_CONNECTION_BROKEN
                        'Its OK not to end the loop. This is possibly a temporary error condition.
                    Case Else
                        EndOfLoop = True
                End Select
                PrintToScreen(LastMQCall & "...." & mqError.Message, False)
                PrintToScreen(LastMQCall & "....RC=" & mqError.Reason, True)
            Finally
                retryCounter = retryCounter + 1
            End Try
        Loop Until EndOfLoop

        '********************************************************
        '    Close the Queue
        '********************************************************
            If thereIsAQueueOpen Then
                LastMQCall = "MQCLOSE"
                Try
                    myQ.Close()
                    PrintToScreen(LastMQCall & "....RC=0000", False)
                    PrintToScreen("Succesfully closed " & myQ.Name, True)
                Catch mqError As MQException
                    PrintToScreen(LastMQCall & "...." & mqError.Message, False)
                    PrintToScreen(LastMQCall & "....RC=" & mqError.Reason, True)
                End Try
            End If

        '********************************************************
        '    Disconnect from the Queue Manager
        '********************************************************
            If thereIsAQueueManagerConnected = True Then
                LastMQCall = "MQDISC"
                Try
                    myQM.Disconnect()
                    PrintToScreen(LastMQCall & "....RC=0000", False)
                    PrintToScreen("Succesfully disconnected from " & myQM.Name, True)
                Catch mqError As MQException
                    PrintToScreen(LastMQCall & "...." & mqError.Message, False)
                    PrintToScreen(LastMQCall & "....RC=" & mqError.Reason, True)
                End Try
            End If
 
        PrintToScreen("Application ended.", True)
        retryCounter = 0

        myHashTable = Nothing
        myQ = Nothing
        myQM = Nothing
        myMsg = Nothing
    End Sub

_________________
Peter Potkay
Keep Calm and MQ On
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » General IBM MQ Support » MQ client auto reconnect
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.