IBM MQ Pubsub message too large - ibm-mq

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.

Related

IBM MQ activity log issue

We are using IBM MQ8.0. Activitiy logs are getting logged for outgoing messages which we are sending to external system. But there is no log available for the messages which are from external system to our MQ Manager.
Is it problem with client channel configuration ?
Or MQ logging configuration issue ?
IBM describes these "activity logs" as recover logs in the Knowledge center page "Making sure that messages are not lost (logging)"
IBM MQ records all significant changes to the persistent data controlled by the queue manager in a recovery log.
This includes creating and deleting objects, persistent message updates, transaction states, changes to object attributes, and channel activities. The log contains the information you need to recover all updates to message queues by:
Keeping records of queue manager changes
Keeping records of queue updates for use by the restart process
Enabling you to restore data after a hardware or software failure
Please note that non-persistent messages are not logged to the recover log.
Based on your question it is likely that the messages you are sending to the external system are persistent messages and the messages you are receiving from the external system are non-persistent messages, this would explain why they are not logged to the recover log files.
Persistence is determined at the time the message is first PUT.
IBM has a good Technote "Message persistence FAQs" about this subject.
Q3. What is the best way to be certain that messages are persistent?
A3. Set MQMD message persistence to persistent (MQPER_PERSISTENT), or nonpersistent (MQPER_NOT_PERSISTENT) and your message will always retain that value.
Note: MQPER_PERSISTENCE_AS_Q_DEF is the default setting for the persistence value in the MQMD. See the persistence values listed below.
...
Additional information
MQPER_PERSISTENCE_AS_Q_DEF can lead to unexpected results. If there is more than one definition in the queue-name resolution path, the default persistence attribute is taken from first queue definition in the path at the time of the MQPUT or MQPUT1 call. This queue could be an:
alias queue
local queue
local definition of a remote queue
queue-manager alias
transmission queue
cluster queue
The external system will need to make sure the messages they send you are set as persistent messages if you want them to be logged.

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.

MQ (Websphere 7) persist message to file system

How would I set up MQ so that every message received is immediately written to file system?
I have the "redbooks", but at least need someone at least point me to a chapter or heading in the book to figure it out.
We are a .NET shop. I have written C# via API to read the queue, and we currently use BizTalk MQ adapter. Our ultimate goal is to write same message to multiple directories in file system to "clone" the feed for our various test environments (DEV, STAGE, TRAINING, etc..). The problem with BizTalk is that when we consume the message, we map it at the same time to a new message, so the message is already changed, and we want the original raw message to be cloned, not the morphed one. Our vendors don't offer multiple copies of the feed, for example, they offer DEV and PROD, but we have 4 systems internally.
I suppose I could do a C# Windows Service to do it, but I would rather use built-in features of MQ if possible.
There is no configuration required. If the message is persistent, WMQ writes it to disk. However, I don't think that's going to help you because they are not written as discrete messages. There's no disk file to copy and replication only works if the replicated QMgr is identical to the primary and is offline during the replication.
There are a number of solutions to this problem but as of WMQ V7, the easiest one is to use the built-in Pub/Sub functionality. This assumes that the messages are arriving over a QMgr-to-QMgr channel and landing on a queue where you then consume them.
In that case, it is possible to delete the queue and create an alias of the same name over a topic. You then create a new queue and define an administrative subscription that delivers messages on the topic into the new queue. Your app consumes from the new queue.
When you need to send a feed to another QMgr or application, define a new subscription and point it at the new destination queue. Since this is Pub/Sub, MQ will replicate the original message as many times as there are subscriptions and the first application and its messages are not affected. If the destination you need to send to isn't accessible over MQ channels (perhaps DEV and QA are not connected, for example), you can deliver the messages to the new queue, use QLoad from SupportPac MO03 to write them to a file and then use another instance of QLoad to load them onto a different QMgr. If you wanted to move them in real time, you could set up the Q program from SupportPac MA01 to move them direct from the new subscription queue on QMgr1 to the destination queue on QMgr2. And you can replicate across as many systems as you need.
The SupportPacs main page is here.
If all you are using is the Redbooks, you might want to have a look at the Infocenters. Be sure to use the Infocenter matching the version of WMQ you are using.
WMQ V7.0 Infocenter
WMQ V7.1 Infocenter
WMQ V7.5 Infocenter

Automatically clear messages from queue in IBM MQ

I was wondering if there is a way for you to configure a queue to automatically clear messages? We are striving to partially implement a component of our architecture and want to be able to send to the queue, but have the queue automatically remove the messages that are being sent so that we don't have to run scripts, etc to perform the clean-up.
So far the only thing I have been able to find is to run CLEAR QLOCAL or set the messages to expire from the publishing application.
For you use case there are a few options in IBM MQ:
Create a QALIAS that points to a TOPIC object which has a topic string with no subscribers, messages put to the QA will just disappear.
Have the sending application set message expiry.
Use the IBM MQ CAPEXPRY feature to administratively force message expiry at the queue level.
Run a script to issue CLEAR QLOCAL against the queue. There can not be open handles on the queue for this to work.
Programmatically issue the equivalent PCF command to CLEAR QLOCAL against the queue. There cannot be open handles on the queue for this to work.
Run the IBM MQ dmpmqmsg utility against the queue to read and discard the messages.

How to monitor an existing queue from WebSphere MQ?

I have a .NET application that needs to monitor a queue in WebSphere MQ. I need to react to each message without impacting the current process. The client application can't explicity send me the same message.
Can I read a message without removing it from the queue? Can I be notified for each message? Can I configure the MQ to duplicate the current queue?
Is there another solution?
If you are using WMQ v7 then you can do this without any impact to the existing applications other than to change the queue name for one of them.
Currently the message producer and consumer use the same queue. In v7 of WMQ you can create an alias over a topic so that the message producer thinks it's a queue. Then you can create two administrative, durable subscriptions such that one points to the existing input queue and another points to a queue dedicated to your new application.
Of course you are already using v7 since v6 goes out of service next year, right? You can upgrade the QMgr to v7 which enables this behavior while still using v6 client code for the apps.
If you are using WMQ v6 then the MirrorQ program might work for you.
You could change from using a queue to a durable topic and have both your reader and your browser subscribe to it.
You could also create a distribution list on your queue manager. A distribution list is used to send a copy of the same message to multiple queues. You would then have a processing queue and a browsing/monitoring queue.

Resources