IBM XMS.Net Listener Hangs Out when connection is closed forbiddenly - ibm-mq

Hi I use webpshere mq client 8.0.0.8 and I set my listener at once and start to listen mq,but something went wrong and and myconnection is closed but it throws no error and mylistener hang out and cant listen message.If its throws error I have a mechanism to catch and restart it but that time I failed.Is there any property set to avoid this issue?
I have exceptionlistener and reconnect options in my connectionproperties.But this is not directly work,I have a autoresetevent (receiveCompleteEvent)mechanism,only solution I can find set signal in exceptionlistener,and kill connection.In exception listener I can log connection error notifications but no automatic connection set,
connectionfactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT);
connectionfactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, 150);
private void OnException(Exception ex)
{
QueueStatuslog.Error(String.Format("Unexpected error occured to connection:{0}", ex.ToString()));
try
{
if (receiveCompleteEvent != null)
{
QueueStatuslog.Error(String.Format("Due to connection error send stop signal:{0}", ex.ToString()));
receiveCompleteEvent.Set();
}

Exception, like connection related, will be thrown to application when application makes synchronous MQ API call, like consumer.receive or producer.send. If you are using message listener to receive messages, the message delivery is an asynchronous operation and messages are delivered on the message listener thread. So XMS can not throw exceptions on that thread. Hence it requires another thread, i.e. ExceptionListener to let the application know about any connection related issues.
You will need to setup ExceptionListener on connection and catch any exception thrown. When an exception is thrown, issue Connection.Stop, clean up and reinitialize message receive.
You can also look at using automatic client reconnection and this.

Related

Facing issues in IBM MQ testing using JMeter

I am working on IBM MQ Performance testing using JMeter. Currently while executing the script i am facing error message. I am able to connect this IBM MQ using RHF utility manually. But in JMeter, i am getting below error. May i know how to fix this error.
Error :
Response message:javax.script.ScriptException: com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'CLDACEAPD' with connection mode 'Client' and host name '172.XX.XX.XX(1414)'.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.
Look at jmeter.log file, the full exception details should be there, look for the string which starts with Caused by and see what is the real cause of the issue.
If it's not there surround your code which establishes the connection with the queue manager into try block and populate the catch block as follows:
try {
//your code here
}
catch (Exception ex) {
log.error('Failed to connect to IBMMQ instance', ex)
}
Additional logging for IBMMQ client can be enabled by setting the following system properties:
com.ibm.msg.client.commonservices.trace.status=ON
com.ibm.msg.client.commonservices.trace.level=9
com.ibm.msg.client.commonservices.trace.outputName=/path/to/ibbmq/client.log

JMS - producer is closed

The following code is trying to send a message on a queue using JMS.
connection = jmsConnectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(queueName);
MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
It works most of the time but while running a stress tests where many messages were sent in parallel, I found once the exception below:
Caused by: javax.jms.IllegalStateException: The producer is closed
at org.apache.activemq.ActiveMQMessageProducer.checkClosed(ActiveMQMessageProducer.java:195)
at org.apache.activemq.ActiveMQMessageProducerSupport.setDeliveryMode(ActiveMQMessageProducerSupport.java:136)
The exception is thrown in the setDeliveryMode().
I have seen other posts about the same issue, but in my case I am not using shared sessions, nor shared connections.
I am running ActiveMQ 5.14.5.
Looking at the code for org.apache.activemq.ActiveMQMessageProducer the closed variable (which is checked by the checkClosed() method at the top of the stack-trace) is initialized as false so something else has to be setting it to true for this exception to be thrown. From what I can see it is only set to true when the producer itself, the originating session, or originating connection is closed. It's possible that the connection and/or session is being closed in the background due to some other failure and this exception with the producer is the first visible symptom of that problem.
In any case, without at least some additional details about your code or ideally a minimal, reproducible example it's not really possible to draw a reliable conclusion.

why is the TcpSendingMessageHandler or TcpOuboundGateway expecting a reply?

The channel adapter is for one way communication.
But while using TcpSendingMessageHandler, the adapter is expecting a reply. and the following message is thrown same is the case with TcpOutboundGateway.
TcpNetConnection : Read Exception [Connection ID] Socket Exception : software caused connection abort: recv failed
Please help me to overcome this issue.
The sending adapter is not expecting a reply; it is possible, however, that the application has collaborating channel adapters (a receiving adapter that uses the same connection).
Even if there is no listener, we have to read from the socket so we can log that an unexpected reply was received. If we don't read from the socket, the peer could end up blocking when the buffers fill up.
What problem is this causing you?
This is typically only logged at DEBUG or TRACE level.

Multi Instance MQ set up

I am trying to set up Multi Instance MQ. I have configured NFS and able to see the active and stand by instances using dspmq -x. However my doubt is after this setup how to proceed further.
How can I configure the channel(s). I got CONNAME property should be use for this. e.g. CONNAME(<ip><port>,<ip><port>). I am not aware how to do it exactly.
How many listeners I need to start.
For normal mode of MQ, I follow the below steps:
1. crtmqm QM
2. strmqm QM
3. runmqsc QM
4. runmqlsr -m QM -t tcp -p 1125
5. runmqsc QM
6. define channel(SYSTEM.ADMIN.SVRCONN) chltype(SVRCONN) mcauser('mqm')
For multi-instance MQ, what changes I have to do for the below steps. There are many good documents available for Multi Instance MQ set up, but most of these are limited to how to configure the queue manager with multi-instance. Could anybody please guide me for the remaining steps.
Any guidance is much appreciated.
EDIT
Thanks Shashi and Morag for the guidance.
I have created different listeners on port 1600 in both the servers. I have created the below channel:
DEFINE CHANNEL(MYCHANNEL) CHLTYPE(CLNTCONN) TRPTYPE(TCP)
CONNAME('IP11600),IP2(1600)')
DEFINE CHANNEL(MYCHANNEL) CHLTYPE(SVRCONN) TRPTYPE(TCP) MCAUSER(' ')
Below is the stand alone java code I am using to put a message in queue.
public class MutilInstanceMq
{
public static void main(String[] args)
{
sendMsg("Test Message");
}
public static void sendMsg(String msg)
{
MQQueueConnectionFactory connectionFactory = null;
QueueConnection queueConn = null;
QueueSession queueSession = null;
QueueSender queueSender = null;
TextMessage message = null;
try
{
connectionFactory = new MQQueueConnectionFactory();
connectionFactory.setConnectionNameList("<IP1>(1600), <IP2>(1600)");
connectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
connectionFactory.setQueueManager("MYQM1");
connectionFactory.setChannel("MYCHANNEL");
queueConn = connectionFactory.createQueueConnection(" ","password");
queueSession = queueConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queueSession.createQueue("MYQ"));
queueSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
message = queueSession.createTextMessage(msg);
message.setJMSCorrelationID("12345");
queueSender.send(message);
queueConn.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
With the above code I end up with the below exception while creating the connection.
> com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ0018: Failed to
> connect to queue manager 'MYQM1' with connection mode 'Client' and
> host name 'IP1(1600),IP2(1600)'. Check the queue manager is
> started and if running in client mode, check there is a listener
> running. Please see the linked exception for more information.
Detailed Print stack trace is:
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ0018: Failed to connect to queue manager 'MYQM1' with connection mode 'Client' and host name 'IP1(1600),IP2(1600)'. Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:608)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:236)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:440)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:7062)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6453)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:295)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6230)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:144)
at MutilInstanceMq.sendMsg(MutilInstanceMq.java:40)
at MutilInstanceMq.main(MutilInstanceMq.java:17)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2543' ('MQRC_STANDBY_Q_MGR').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223)
... 8 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2543;AMQ9204: Connection to host 'IP2(1600)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2543;AMQ9487: Remote queue manager is a standby queue manager instance. [3=MYCHANNEL]],3=IP2(1600),5=RemoteConnection.analyseErrorSegment]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:2010)
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1227)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:355)
... 7 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2059;AMQ9204: Connection to host 'IP1(1600)' rejected. [3=IP1(1600)]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1980)
... 9 more
Where I am going wrong? Meanwhile I have turned off channel authentication and able to connect to the queue.
To answer your explicit questions:
If you want to use the comma-separated CONNAME method, then you'll end up with something like this. CONNAME('machine1(1234),machine2(1234)'). You should have the same port number in both.
You have two options here. Either use runmqlsr on each machine - so you have two listeners, on the same port. The purpose of the one on the primary machine is for connections to be able to connect to the queue manager. The purpose of the one on the standby machine is to reject connections which try to connect there more quickly than they could be rejected by TCP working out that there is no listener. It also means that the error reported by the connection for the reason it could not connect is much more explicit - "This machine is the standby" rather than "no TCP listener here".
The alternate option is to define a LISTENER object and have it controlled by the queue manager, this way it will only run where the queue manager runs. This keeps the configuration all within the queue manager, but does mean you don't get the benefits outlined above.
The steps are well documented in Knowledge Center here: http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_7.1.0/com.ibm.mq.doc/fa70161_.htm?lang=en. How to verify the multi-instance setup is described here: http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_7.1.0/com.ibm.mq.doc/fa70163_.htm?lang=en.

handle over exception in JMS operations

I am using activeMQ 5.4 for JMS implementation in my project.
I want to notify user every time application fails to send a message
but I am not getting any handle at occurrence of an exception.
For instance, In case JMS broker is down and I perform a create connection, session etc. or a message send operation within a try block,
control never comes back to catch block or ExceptionListener set for the connection.
My code looks like:
connection = (TopicConnection) (new ActiveMQConnectionFactory(localBrokerURL)).createConnection();
connection.setExceptionListener(new ExceptionListener() {
#Override
public void onException(JMSException arg0) {
System.out.println("Exception Occurred");
}
});
connection.start();
final TopicSession session =conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
final Topic sendTopic = session.createTopic("someTopicName");
where Value of localBrokerURL is
failover://(ssl://localhost:61618?trace=true&wireFormat.maxInactivityDuration=0)
Please help. Any hint is highly appreciated.
that is the intent of the failover: transport. It will hide transport failures and automatically try and reconnect, replaying any jms state when a new connection is established.
There is a transportListener that you can use to get transport suspended and resumed events.
If you remove the failover: component from the broker url, you will get all exceptions propagated up to your client.
just set the timeout property on the connection URI and it will throw an error instead of block the thread...
failover://(ssl://localhost:61618?trace=true&wireFormat.maxInactivityDuration=0)?timeout=10000
see http://activemq.apache.org/failover-transport-reference.html

Resources