|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
MQ client auto reconnect |
« View previous topic :: View next topic » |
Author |
Message
|
felfel |
Posted: Tue Jul 15, 2008 1:40 am Post subject: MQ client auto reconnect |
|
|
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 |
|
 |
bruce2359 |
Posted: Tue Jul 15, 2008 6:49 am Post subject: |
|
|
 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 |
|
 |
omhopper |
Posted: Tue Jul 15, 2008 6:54 am Post subject: MQ client auto reconnect |
|
|
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 |
|
 |
zpat |
Posted: Tue Jul 15, 2008 7:34 am Post subject: |
|
|
 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 |
|
 |
PeterPotkay |
Posted: Tue Jul 15, 2008 1:47 pm Post subject: |
|
|
 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 |
|
 |
|
|
 |
|
Page 1 of 1 |
|
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
|
|
|
|