Author |
Message
|
DAEMON |
Posted: Wed Feb 01, 2006 9:33 am Post subject: Help please |
|
|
Newbie
Joined: 01 Feb 2006 Posts: 5
|
I am faced with a peculiar problem. Please read on...
Some Background:
I have written a windows application that calls a web service. The web service in turn uses the classes in amqmdnet.dll, which is a library provided by IBM MQ for .NET to connect and post messages to a Queue on an MQ server . The win app makes this call in a loop. It does so successfully around 3950 times, after which it gives an error. However if I introduce a time lag of 50 milliseconds between each iteration of the loop this error does not occur.
With regards to the error returned by MQ Manager:
MQRC_Q_MGR_NOT_AVAILABLE
Which corresponded to this entry in the event log:
The program could not bind to a TCP/IP socket.
The attempt to bind to socket '0' failed with return code 10048. The failing TCP/IP call was 'bind'. The most likely cause of this problem is incorrect configuration of the TCP/IP local address or incorrect start and end port parameters.
Contact the system administrator. If the problem persists contact your IBM support center.
***************************************
The worst part is that it does not go into the exception block when an attempt to connect to the queue manager or the queue or when I attempt to put a message fails. Because of this I cant even employ a retry.
Any suggestions from anyone who has faced this particular problem or has any clue as to what is going on please please reply.
Thanks in advance.
Kind Regards,
D. |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Feb 01, 2006 9:44 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Are you opening a new connection to MQ every time through your loop?
If so, don't. It's a bad thing to do, and could be causing your problem. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
DAEMON |
Posted: Thu Feb 02, 2006 3:46 am Post subject: |
|
|
Newbie
Joined: 01 Feb 2006 Posts: 5
|
Due to the nature of its design, I do end up openign a new connection for every iteration of the loop.
Let me post the code I use:
The windows app that runs the loop:
//object of the webservice that calls this method
MQS objMQPut = new MQS();
for (i = 0; i< 5000 ; i++)
{
try
{
retval = objMQPut.Send(txtBx_Data.Text) + " : " + (iTimes).ToString() + " times" ;
}
catch(Exception ex)
{
txtBx_Exception.Text = txtBx_Exception.Text + " >>>>>>>> EXCEPTION: " + ex.Message.ToString() ;
Thread.Sleep(50);
}
}
The webservice method being called:
[WebMethod]
public string Send(string strMsg)
{
try
{
//object of component that connects to MQ
MQServerPut obj = new MQServerPut();
//this port is not used by any other application
obj.HOST = "localhost(1450)";
obj.QMGR = "myQmgr";
obj.Channel = "MyCHANNEL";
obj.QUE = "MyQ";
obj.PutMessage(strMsg);
return "Message sent";
}
catch(Exception ex)
{
throw new SoapException(ex.Message.ToString(), SoapException.ServerFaultCode ) ;
}
}
The component used by the webservice
public bool PutMessage(string strMsg)
{
try
{
try
{
mqQMgr = new MQQueueManager(strQMGR,MQC.MQCNO_HANDLE_SHARE_BLOCK,strChannel,strHOST);
}
catch(Exception mex)
{
strErrorReason = mex.Message.ToString();
throw new Exception(strErrorReason );
}
try
{
mqQueue = mqQMgr.AccessQueue( strQUE, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING );
}
catch(Exception mex)
{
strErrorReason = mex.Message.ToString();
throw new Exception(strErrorReason );
}
mqMsg.WriteString( strMsg );
mqMsg.Format = MQC.MQFMT_STRING;
try
{
mqQueue.Put( mqMsg, mqPutMsgOpts );
mqMsg.ClearMessage();
}
catch (Exception mex)
{
strErrorReason = mex.Message.ToString();
throw new Exception(strErrorReason );
}
mqQueue.Close();
mqQMgr.Close();
mqQMgr.Disconnect();
while(mqQueue.IsOpen)
{
//wait till queue closes.
}
while(mqQMgr.IsConnected)
{
//wait till queue manager disconnects.
}
return true;
}
catch(Exception ex)
{
throw new Exception(ex.ToString(),ex);
}
}
Do let me know if I need to change anything or if Im doing anything wrong
Thanks in advance,
D. |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Feb 02, 2006 4:47 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
DAEMON wrote: |
Due to the nature of its design, I do end up openign a new connection for every iteration of the loop. |
You need to change the code so it doesn't do this. Opening a connection to MQ is like opening a connection to a database - slow and expensive.
Open your connection once, run through your loop, and then close it. You should not then need to put in the delays that you are complaining about. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
DAEMON |
Posted: Thu Feb 02, 2006 6:05 am Post subject: |
|
|
Newbie
Joined: 01 Feb 2006 Posts: 5
|
Hi Jeff,
Thanks for the quick reply.
However the loop will be run at the application level. The connection opens at the component level.
App [A]
Webservice [B]
Webservice Component [C]
A (loop*5000)->B->C(open conn-put msg-close conn)
A calls B via http.
A is a sample app used to stress test B which connects and drops msgs to to the queue and disconnects thereafter.
A cannot be concerned with the details of MQ connectivity. All it does is prepare messages to be sent.
Im really out of ideas on this one.
Is it that MQ is not able to close the connections quickly enough?
Thanks & Regards,
D. |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Feb 02, 2006 6:38 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
The connection can be cached in the component, for example using a Singleton pattern. Create the connection if it doesn't exist, stick it in some persistant across invocations memory, and reuse it until it breaks or you know you can close it.
Or you can change the component call to pass in a connection, instead of not passing in a connection. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
mvic |
Posted: Thu Feb 02, 2006 6:46 am Post subject: |
|
|
 Jedi
Joined: 09 Mar 2004 Posts: 2080
|
DAEMON wrote: |
Is it that MQ is not able to close the connections quickly enough? |
The problem you've documented is a faliure of the bind() call. The error number is 10048 - Address in Use.
This is a Windows sockets call - the reason for its failing is not necessarily attributable to MQ. What if (I'm just wondering, not asserting) the failure is because Windows sockets is locking us out from bind() for a short period - eg. 50 milliseconds?
One other question : Do you have the MQTCPSDRPORT environment variable set in your process at the time the MQ connection is made? |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Feb 02, 2006 6:50 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
mvic wrote: |
What if (I'm just wondering, not asserting) the failure is because Windows sockets is locking us out from bind() for a short period - eg. 50 milliseconds? |
I suspect that Daemon is using up his max channels, or his maxhands. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
|