Connecting Queue manager with multiple threads - ibm-mq

We are trying to publish messages on a topic using multiple connection handles for a queue manager. We are using threads for this.
However when we use fifty threads the messages are properly pulbished on to the topic but as we go on increasing the threads, to say 500, we get the following reason codes 2071,2012,2538 for some threads and then the program crashes giving reason code as 2059 for remaining threads
I thought that may be due to restriction on the number of connection handle we are getting these errors. So I tried
1. adding channels stanza to qm.ini file
CHANNELS:
MaxChannels=<number>
MaxActiveChannels=<number>
2. altering MAXHANDS of my queuemanager to 2000
But found no luck in the above approaches.
Kindly help me in solving this issue.
PS. We have created our own Library for calling websphere MQ API.
Thanks,
Mandar.

Suggest you try increasing the Shared Conversation (SHARECNV) value on the server connection channel you are using for connecting to queue manager.
In runmqsc shell run the following command to alter the SHARECNV for the channel.
alter channel <your SVRCONN channel name> chltype(SVRCONN) sharecnv(<say 100>)

Related

IBM MQ Pubsub message too large

I have a Normal IBM MQ developer edition 924 installed on a ubuntu virtual machine. And have cpp code files for Publisher and Subscriber model. I created a topic and started sending messages on the topic.
The issue happens when I send a larger message on the topic, the error code of 2031(MQRC_MSG_TOO_BIG_FOR_Q_MGR) is outputted. (https://www.ibm.com/docs/en/ibm-mq/9.1?topic=arc-2031-07ef-rc2031-mqrc-msg-too-big-q-mgr)
I changed the maxmsgl value for the Queue manager and the SVR channel as well. I ran the following commands for this:
runmqsc QM1
ALTER QMGR MAXMSGL(104857600)
ALTER CHANNEL(SYSTEM.AUTO.SVRCONN) CHLTYPE(SVRCONN) maxmsgl(104857600)
But still the error persists, could someone reflect on what needs to be done regarding this error code. And also as message segmentation is not allowed on pubsub what is the maximum limit of message size it can handle.
When using a topic for publish/subscribe, the messages sent to subscribers are still put onto a queue for safe storage until they are consumed by the subscribing/getting application. These queues must also have MAXMSGL set appropriately.
If you do not know which queue to adjust, follow these steps:-
Run the subscriber application - assuming that it will wait around for a while
Issue the following MQSC command (e.g. using runmqsc):-
DISPLAY SUB(*) DEST DESTCLAS TOPICSTR DURABLE
The name shown in the DEST field in the output is the queue your subscription is using. If it's name starts with SYSTEM.MANAGED and it also shows DESTCLAS(MANAGED) then your subscription is a managed subscription. You say that your subscription is not managed, but if you don't know which queue is in use by that subscriber then it is most likely that it IS managed, since that means you don't have to worry about the queue.
A managed subscription queue is built from a MODEL queue referenced on the topic. If you are unsure which MODEL queue would be used, issue the following command using the TOPICSTR value from the output of the above command.
DISPLAY TPSTATUS('topic-str-value') MNDURMDL MDURMDL
If the output from the DISPLAY SUB command earlier showed that your subscription was DURABLE(YES) then the MODEL queue in use is the one shown in the field MDURMDL (Managed DURable MoDeL). If it showed DURABLE(NO) then the MODEL queue in use is the one shown in the field MNDURMDL (Managed Non-DURable MoDeL).
Using the name determined in step 4 if it is not managed, or in step 5 if it is managed, issue the following MQSC command:-
ALTER QLOCAL('q-name-from-step-4') MAXMSGL(104857600)
or
ALTER QMODEL('q-name-from-step-5') MAXMSGL(104857600)
Now re-make your subscription (so that it deletes the previous temporary queue it created and makes a new one from the model) and re-run your publisher application.

Way to automatically clear all applications connected to the queue

We have an environment where MQ acts as an interface between
Websites and Micro Focus. Sometimes a message gets stuck in a queue,
thereby blocking all the communications over that particular queue. If
the queue depth increases greatly, all the communication stops in the
queue manager.
When we check the status of queue, we see that microfocus process is present there.
Is there are way to automatically clear all applications connected to the queue?
I don't think its possible to close an applications handle on a given queue but you could have a script that runs a couple of MQSC commands against the queue manager to first get the connection identifier using the DISPLAY CONN command and then close the connection using the STOP CONN command. You could then setup a trigger on the queue that executes the script once a certain queue depth has been reached.

MQ: Same queue name under 2 queue manager

I have two MQ queue manager with same queue names configured. Both are configured to send data to different servers. Currently queue manager(QM1) is stopped(status Ended Immediately) and QM2 is running
Now my program opens the queue and sends data. It doesnot specify queue manager name. When I execute the program, MQ connection request returns error 2059.
My questions are:
What happens when multiple queue managers have same queue name?
How to tackle situation without changing the code?
Please forgive if the description is vague. It would be helpful if anyone provide links so that newbie like me can learn something.
Thanks
It would be helpful if could provide details on your application. Whether it's using server bindings or client mode connection to queue manager. What version of MQ are you using?
The below information is valid for MQ v7.x:
If you are using client mode then you can use multiple CONNNAMEs to connect. If one queue manager is down, your application will connect to next queue manager in CONNAME list. One of the simplest way to do when using client mode connection is to define MQSERVER environment variable and specify multiple CONNNAMEs.
SET MQSERVER=<channel name>/TCP/host1(port1), host2(port2)
For example when both queue managers are on local host:
SET MQSERVER=MYSVRCONCHN/TCP/localhost(1414),localhost(1415)
In server bindings mode if queue manager name is not specified, then application will attempt to connect to the default queue manager. If the default queue manager is down, then 2059 is thrown.
Your explaination doesn't provide clarity about your requirements.
You wrote:
My questions are 1. What happens when multiple queue managers have same queue name.
Nothing. Its a normal scenario. Different queue managers may have queues with same name and it doesn't create any ambiguity. Although, scenario will be a little different when the queue managers are in same cluster and the queue is also a cluster queue. Then everything will depend on requirements and design.
You wrote:
2. How to tackle situation without changing the code
Run the queue manager which is stopped.
You wrote:
Now my program opens the queue and sends data. It doesnot specify
queue manager name.
What application are you using?For a client application, you access a queue using an object of queue manager.
I am asssuming that you are using an application(client) which doesn't take queue manager details from you, only takes queue details. And may be the queue manager is hard coded within the code. And it sends the message first to the queue of Queue manager 1 and then to queue manager 2. But, in your case queue manager 1 is down.
If above is the case, then the application's code needs to be changed. You should have exception handling in such a way that it executes the code for sending the message to the second queue manager even though the first lines of code throws error.

Clear messages from mq using java

What is the best approach to connect to websphere mq v7.1 and clear all the messages of one or more specified queues using Java and JMS? Do I need to use Websphere MQ specific java API? Thanks.
Like all good questions, "it depends."
The queue can be cleared with a command only if there are no open handles on the queue. In that case sending a PCF command to clear the queue is quite effective, but if there are open handles you get back an error. PCF commands are of course a Java feature and not JMS because they are proprietary to WebSphere MQ.
On the other hand, any program authorized to perform destructive gets off a queue can clear the queue. In this case, just loop over a get until you get the 2033 return code indicating the queue is empty. This can be performed using JMS or Java but both of these manage the input buffer for you. If the queue is REALLY deep then you end up moving all that data and if the app is client connected, you are moving it at network speed instead of in memory.
To get around this, you need to specify a minimal amount of buffer and as one of the GET options also specify MQGMO.TRUNCATED_MSG_ACCEPTED. This moves only the message header during the get calls and can be significantly faster.
Finally, if you are doing this programamtically and regardless of which method you use, spin off several threads and don't use syncpoint. You actually have to go out of your way to get exclusive input on a queue so once you get a session, just spawn many threads off of it. Close each thread gracefully and shut down the the session once all the threads are closed.

IBM MQ Message Throttling

We are using IBM MQ and we are facing some serious problems regarding controlling its asynchronous delivery to its recipient.We are having some java listeners configured, now the problem is that we need to control the messages coming towards listener, because the messages coming to server are in millions count and server machine dont have that much capacity t process so many threads at a time, so is there any way like throttling on IBM MQ side where we can configure preetch limit like Apache MQ does?
or is there any other way to achieve this?
Currently we are closing connection with IBM MQ when some X limit has reached on listener, but doesen't seems to be efficient way.
Please guys help us out to solve this issue.
Generally with message queueing technologies like MQ the point of the queue is that the sender is decoupled from the receiver. If you're having trouble with message volumes then the answer is to let them queue up on the receiver queue and process them as best you can, not to throttle the sender.
The obvious answer is to limit the maximum number of threads that your listeners are allowed to take up. I'm assuming you're using some sort of MQ threadpool? What platform are you using that provides unlimited listener threads?
From your description, it almost sounds like you have some process running that - as soon as it detects a message in the queue - it reads the message, starts up a new thread and goes back and looks at the queue again. This is the WRONG approach.
You should have a defined number of process threads running (start with one and scale up as required, and within limits of your server) which read from the queue themselves. They would each open the queue in shared mode and either get-with-wait or do immediate get with a sleep if you get a MQRC 2033 (no messages in queue).
Hope that helps.
If you are running in the application server environment, then the maxPoolDepth property on the activationSpec will define the maximum ServerSessionPool size for the MDB - decreasing this will throttle the number messages being delivered concurrently.
Of course, if your MDB (or javax.jms.MessageListener in the JSE environment) does nothing but hand the message to something else (or, worse, just spawn an unmanaged Thread and start it) onMessage will spin rapidly and you can still encounter problems. So in that case you need to limit other resources too, e.g. via threadpool configuration.
Closing the connection to the QM is never an efficient way, as the MQCONN/MQDISC cycle is expensive.

Resources