|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Queue Depth and Queue Service Interval |
« View previous topic :: View next topic » |
Author |
Message
|
jed |
Posted: Mon Jun 07, 2004 11:57 pm Post subject: Queue Depth and Queue Service Interval |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
HHhhmm.... Question, question, question....
I've read the Event Monitor manual..
Can the gurus here explain in a few sentences about the Queue Service Interval?
My understanding of this is that there are only two types of queue service intervals it is either (a) An OK event or (b) A HIGH event.
OK event - is when an MQGET is done within a user-defined time period (service interval).
HIGH event - is when an MQGET was NOT done within a user-defined time period.
I've been banging my head on this one 'coz as per IBM docs on the Event Monitoring...... an OK event can be caused by an MQGET call, while a HIGH event can be caused by an MQGET call or an MQPUT call.
Can the gurus here briefly explain why is it so?
Again... I've read the Event Monitor PDF and just need some clarification to shed some light on this part. _________________ Jed |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Jun 08, 2004 3:25 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
The Okay event is basically the "reset" event, if I understand things correctly (and bear it mind it's been a while since I've read this part of the manuals).
Here's the way I understand the sequence of things to occur: - Queue is empty
- Messages are put and get from the queue
- Queue depth crosses the Queue Depth High limit by an MQPut, going from below the limit to above the limit
- Queue Depth High event is thrown, and the threshold is disabled for alerting
- Messages are gotten from the queue
- Queue depth crosses the Queue Depth High limit by an MQGet going from above the limit to below the limit
- Queue depth Okay event is thrown, and Queue Depth High event is reenabled.
Again, this is from my very fallible memory and so likely not reliable. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
jed |
Posted: Tue Jun 08, 2004 4:07 am Post subject: |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
hhhmm.... ok got it a bit jeff...
hope the other gurus put more info into this... _________________ Jed |
|
Back to top |
|
 |
clindsey |
Posted: Tue Jun 08, 2004 5:42 am Post subject: |
|
|
Knight
Joined: 12 Jul 2002 Posts: 586 Location: Dallas, Tx
|
My understanding is that a queue becomes a candidate for a high event when a get is not done within the service interval. The event is not actually triggered until the next get or put, which explains why a high event occurs on either a MQGET or MQPUT.
A low event is then triggered when a get is subsequently done within the service interval.
The service events are not related to queue depth. Those are queue depth events.
Hope this helps,
Charlie |
|
Back to top |
|
 |
jed |
Posted: Tue Jun 08, 2004 11:18 pm Post subject: |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
Hi Jeff and clindsey,
Ok guys thanks, more or less I'm understanding this queue service interval. Just for clarification again, please see below.....
Automatic enabling of queue service interval events
The high and OK events are mutually exclusive; that is, when one is enabled, the other is automatically disabled.
When a high event is generated on a queue, the queue manager automatically disables high events and enables OK events for that queue.
Similarly, when an OK event is generated on a queue, the queue manager
automatically disables OK events and enables high events for that queue.
I cut/paste this from the Event Monitoring document from IBM (page 19).
Here is a scenario below......
Service interval is 10 secs
Service event is HIGH
Service Time Activitiy
1 sec MQPUT
2 sec MQGET
1 secs MQPUT
15 secs MQPUT
30 secs MQGET
15 secs MQGET
MQPUT #1
==> Service Timer ON (starts).
MQGET #1 is within service interval.
==> No event generated, get is within service interval.
==> Service Event still set to HIGH
==> Service Timer is OFF
MQPUT #2
==> Service Timer ON.
MQPUT #3
==> HIGH event generated.
==> Service Event is set to OK.
MQGET #2
==> Service timer reset to zero.
==> No event generated, OK event cannot be generated 'coz Service Event is set to OK.
MQGET #3
==> Service timer is OFF, 'coz queue is now empty.
==> No event generated, OK event cannot be generated 'coz Service Event is set to OK.
NOTE: This Service Event will not be set to HIGH unless an MQGET is made within the Service Interval.
Question:
The above scenario can happen and will/might happen.
What I want is to monitor HIGH events, not the OK events.
How can I set the Service Event to auto change to HIGH?
Of course, the event monitor program that I will inform the production support guys (24 X 7) via email (if possible SMS) that a HIGH event has been detected. This will enable the prod'n support guys to detect and fix the problem.
Is it possible to auto change the Service Event to HIGH? Or, should I just let the prod'n to manually change the Service Event from OK to HIGH?
I think I prefer letting the prod'n support handle the changing of the Service Event (though this is prone to error 'coz manual intervention).
You guys have any suggestions???
Rgds,
JD _________________ Jed |
|
Back to top |
|
 |
frankdk |
Posted: Thu Jun 10, 2004 12:24 pm Post subject: |
|
|
 Novice
Joined: 10 Jun 2004 Posts: 20 Location: Copenhagen, Denmark
|
Hi
This is maybe an easier way to understand:
A MQPUT will start the "service timer" if it's not running ie. on first put.
On MQGET the timer will be checked and:
- If it's abve the service interval AND high alerts are enabled it will generate a high alert.
- If it's below the service interval AND OK events are enabled it will generate an OK event.
A MQGET will also restart the "service timer"
On MQPUT there will be a check to see (as per above) to see if the timer is above and that may generate a high event (if enabled).
There is no reset of the timer on put as it is ment to monitor get times.
Regards
Frank |
|
Back to top |
|
 |
jed |
Posted: Thu Jun 10, 2004 5:58 pm Post subject: |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
Thanks for the brief summary Frank... But.....
The thing that puzzles me is, how can I reset back the Service Interval Event from OK to HIGH with manual intervention. _________________ Jed |
|
Back to top |
|
 |
frankdk |
Posted: Fri Jun 11, 2004 1:50 am Post subject: |
|
|
 Novice
Joined: 10 Jun 2004 Posts: 20 Location: Copenhagen, Denmark
|
The question is if you want to enable the OK event or if you want to generate the OK event?
To enable the OK eventuse: ALTER QLOCAL(...) QSVCIEV(OK) - This status will normally be set when a service interval high event is generated.
To have the service interval OK event to pop you need messages on the queue - and you need to do MQGET too!
I'm not 100% sure what your problem is, could you clarify the situation? _________________ Regards,
Frank |
|
Back to top |
|
 |
jed |
Posted: Fri Jun 11, 2004 3:42 am Post subject: |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
Frank, I know how to enable the event.
I think I've stated my question quite clearly on the earlier posting.
Would be easier if you read my previous posting...
But, to repeat.......
HIGH event occurs, Service event enables OK.
I want to monitor only HIGH events, what should I do?
My answer is: Since I'm going to alert the prod'n support via email and/or sms, I'd let them manually revert the Service Event to HIGH. _________________ Jed |
|
Back to top |
|
 |
clindsey |
Posted: Fri Jun 11, 2004 7:40 am Post subject: |
|
|
Knight
Joined: 12 Jul 2002 Posts: 586 Location: Dallas, Tx
|
JD,
Sorry, I have been busy and not able to monitor the forum the past couple of days.
Let me make sure a couple of fundamentals are clear. If you enable a queue for service events and set the timer interval, when an event is triggered, a PCF message is written to SYSTEM.ADMIN.PERFM.EVENT.
You have to provide the monitoring code to take actions on the event messages.
I believe then to accomplish what you desire, your monitor program would act on MQRC_Q_SERVICE_INTERVAL_HIGH and alert your ops team. The ops team cannot specifically reset events, but they may start some process or additional processes to service the queue and remove messages. At some point the queue service interval will fall within criteria and your monitor will get a MQRC_Q_SERVICE_INTERVAL_OK event. You can just ignore this event or write to a log, etc but do not involve ops.
I hope that helps. I have some c code that monitors for events and just writes to std out This is helpful in understanding events and doing proof of concept. If you are interested, let me know and I will post it here.
Charlie |
|
Back to top |
|
 |
bbburson |
Posted: Fri Jun 11, 2004 11:09 am Post subject: |
|
|
Partisan
Joined: 06 Jan 2004 Posts: 378 Location: Nowhere near a queue manager
|
Quote: |
Service interval is 10 secs |
Are you sure it's set to 10 seconds and not 10 milliseconds? I have been experimenting today and was seeing similar results to yours (QSVCIEV was set to OK and would not automatically change back to HIGH when the queue was emptied).
I was reading the Events manual for further clarification and realized the value specified in QSVCINT is in milliseconds, not seconds. After I changed my queue definition to QSVCINT(10000), the QSVCIEV attribute changed back and forth between HIGH and OK automatically as I had originally thought it should. |
|
Back to top |
|
 |
jed |
Posted: Sat Jun 12, 2004 5:45 am Post subject: |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
Its ok clindsey.... I've just finished configuring SSL again with another client (with fail-over server).
Well, I'll try to look into this more and thanks for your help.
I'll just give the ops the steps in changing the Service Interval from HIGH to OK. But, I'll also include in the program to just disregard the OK event.
Bruce, I was just using 10secs as an example. I know 10secs is a looong time in MQ. Its actually 10 msecs.
And, thanks for confirming the points I've discussed. I was just using my understanding and imagination on it.
Darn it.... I need to finish my API program by the end of next week.....
Plus, need to learn this MQSI and QPASA thing...
You guys have any docs on QPASA? _________________ Jed |
|
Back to top |
|
 |
clindsey |
Posted: Sat Jun 12, 2004 6:13 am Post subject: |
|
|
Knight
Joined: 12 Jul 2002 Posts: 586 Location: Dallas, Tx
|
JD, here is the code I mentioned. Maybe it will save you a little time on your api work.
Code: |
/********************************************************************/
/* */
/* Program name: eventmsg.c */
/* */
/* Description: test reading event messages using MQBAG */
/* */
/* Setup: queue manager must be enabled for performance */
/* events. ( PERFMEV(enabled) ) */
/* A test queue must be enabled for service events */
/* QSVCIEV(HIGH) + QSVCINT(120000) */
/* **vcint time is milliseconds** */
/* */
/* and/or queue depth events */
/* QDPHIEV(ENABLED) */
/* QDEPTHLO(20) */
/* QDEPTHHI(60) */
/* **high/low depths are % of MAXDEPTH** */
/* */
/* Syntax: eventmsg queuename */
/* default queuename is SYSTEM.ADMIN.PERFM.EVENT */
/********************************************************************/
/* */
/* Results: */
/* */
/* */
/* Performance Events: */
/* queue depth high: */
/* mqrc MQRC_Q_DEPTH_HIGH */
/* str attrs MQCA_Q_MGR_NAME */
/* MQCA_BASE_Q_NAME */
/* int attrs MQIA_TIME_SINCE_RESET */
/* MQIA_HIGH_Q_DEPTH */
/* MQIA_MSG_ENQ_COUNT (puts since last reset) */
/* MQIA_MSG_DEQ_COUNT (gets since last reset) */
/* */
/* queue depth low: */
/* mqrc MQRC_Q_DEPTH_LOW */
/* str attrs MQCA_Q_MGR_NAME */
/* MQCA_BASE_Q_NAME */
/* int attrs MQIA_TIME_SINCE_RESET */
/* MQIA_HIGH_Q_DEPTH */
/* MQIA_MSG_ENQ_COUNT */
/* MQIA_MSG_DEQ_COUNT */
/* */
/* queue full: */
/* mqrc MQRC_Q_FULL */
/* str attrs MQCA_Q_MGR_NAME */
/* MQCA_BASE_Q_NAME */
/* int attrs MQIA_TIME_SINCE_RESET */
/* MQIA_HIGH_Q_DEPTH */
/* MQIA_MSG_ENQ_COUNT */
/* MQIA_MSG_DEQ_COUNT */
/* */
/* queue service interval high: */
/* mqrc MQRC_Q_SERVICE_INTERVAL_HIGH */
/* str attrs MQCA_Q_MGR_NAME */
/* MQCA_BASE_Q_NAME */
/* int attrs MQIA_TIME_SINCE_RESET */
/* MQIA_HIGH_Q_DEPTH */
/* MQIA_MSG_ENQ_COUNT */
/* MQIA_MSG_DEQ_COUNT */
/* */
/* queue service interval ok: */
/* mqrc MQRC_Q_SERVICE_INTERVAL_OK */
/* str attrs MQCA_Q_MGR_NAME */
/* MQCA_BASE_Q_NAME */
/* int attrs MQIA_TIME_SINCE_RESET */
/* MQIA_HIGH_Q_DEPTH */
/* MQIA_MSG_ENQ_COUNT */
/* MQIA_MSG_DEQ_COUNT */
/* */
/* */
/* */
/********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/********************************************************************/
/* includes for MQI */
/********************************************************************/
#include <cmqc.h>
#include <cmqcfc.h>
#include <cmqbc.h>
#define BUFFER_SIZE 256
void CheckCallResult(char *callText, MQLONG cc, MQLONG rc);
int main(int argc, char **argv)
{
/******************************************************************/
/* Declare MQI structures needed */
/******************************************************************/
MQOD od = {MQOD_DEFAULT}; /* Object Descriptor */
MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */
MQGMO gmo = {MQGMO_DEFAULT}; /* get message options */
MQHCONN Hcon = 0; /* connection handle */
MQHOBJ Hobj = 0; /* object handle */
MQLONG O_options = 0; /* MQOPEN options */
MQLONG C_options = 0; /* MQCLOSE options */
MQLONG CompCode = 0; /* completion code */
MQLONG OpenCode = 0; /* MQOPEN completion code */
MQLONG Reason = 0; /* reason code */
MQLONG CReason = 0; /* reason code for MQCONN */
MQLONG itemValue = 0; /* item value */
char QMName[50]; /* queue manager name */
MQCHAR strData[BUFFER_SIZE]= ""; /* string data */
MQLONG strDataLen = sizeof(strData);
MQHBAG replyBag=MQHB_UNUSABLE_HBAG;/* reply bag */
/******************************************************************/
/* Connect to queue manager */
/******************************************************************/
QMName[0] = 0; /* default queue manager */
if (argc > 2)
strcpy(QMName, argv[2]);
MQCONN(QMName, &Hcon, &CompCode, &CReason);
if (CompCode == MQCC_FAILED)
{
CheckCallResult("MQCONN", CompCode, CReason);
exit(1);
}
/******************************************************************/
/* Initialize object descriptor for subject queue */
/******************************************************************/
strcpy(od.ObjectName, "SYSTEM.ADMIN.PERFM.EVENT");
if (argc > 1)
{
strcpy(od.ObjectName, argv[1]);
}
/******************************************************************/
/* Open the event queue for input; exclusive or shared. Use of */
/* the queue is controlled by the queue definition here */
/******************************************************************/
O_options = MQOO_INPUT_AS_Q_DEF
+ MQOO_FAIL_IF_QUIESCING;
MQOPEN(Hcon, &od, O_options, &Hobj, &CompCode, &Reason);
if (Reason != MQRC_NONE)
{
MQDISC(&Hcon, &CompCode, &Reason);
CheckCallResult("MQOPEN", CompCode, Reason);
exit(2);
}
OpenCode = CompCode;
printf("now monitoring queue %s\n", od.ObjectName);
/******************************************************************/
/* Get messages from the message queue */
/******************************************************************/
if (Reason == MQRC_NONE)
{
mqCreateBag(MQCBO_COMMAND_BAG, &replyBag, &CompCode, &Reason);
CheckCallResult("mqCreateBag", CompCode, Reason);
}
gmo.Options = MQGMO_WAIT + MQGMO_CONVERT;
gmo.WaitInterval = MQWI_UNLIMITED;
while (Reason == MQRC_NONE)
{
memcpy(md.MsgId, MQMI_NONE, MQ_MSG_ID_LENGTH);
memcpy(md.CorrelId, MQMI_NONE, MQ_MSG_ID_LENGTH);
memcpy(md.Format, MQFMT_EVENT, MQ_FORMAT_LENGTH);
mqGetBag(Hcon, Hobj, &md, &gmo, replyBag, &CompCode, &Reason);
CheckCallResult("mqGetBag", CompCode, Reason);
/*********************************************************************/
/* Check the compCode and reason */
/*********************************************************************/
if (Reason == MQRC_NONE)
{
mqInquireInteger(replyBag, MQIASY_REASON, MQIND_NONE, &itemValue,
&CompCode, &Reason);
CheckCallResult("mqInquireInteger", CompCode, Reason);
printf("\nEvent reason code:");
switch (itemValue)
{
case MQRC_Q_DEPTH_HIGH:
printf(" MQRC_Q_DEPTH_HIGH (%ld)\n", itemValue);
break;
case MQRC_Q_DEPTH_LOW:
printf(" MQRC_Q_DEPTH_LOW (%ld)\n", itemValue);
break;
case MQRC_Q_FULL:
printf(" MQRC_Q_FULL (%ld)\n", itemValue);
break;
case MQRC_Q_SERVICE_INTERVAL_HIGH:
printf(" MQRC_Q_SERVICE_INTERVAL_HIGH (%ld)\n", itemValue);
break;
case MQRC_Q_SERVICE_INTERVAL_OK:
printf(" MQRC_Q_SERVICE_INTERVAL_OK (%ld)\n", itemValue);
break;
default:
printf(" unexpected code (%ld)\n", itemValue);
}
} /* endif */
/*********************************************************************/
/* Now print out any user selectors containing diagnostics */
/*********************************************************************/
if (Reason == MQRC_NONE)
{
mqInquireString(replyBag, MQCA_BASE_Q_NAME, 0, MQ_Q_NAME_LENGTH, strData,
&strDataLen, NULL, &CompCode, &Reason);
if (CompCode == MQCC_OK && Reason == MQRC_NONE)
{
mqTrim(MQ_Q_NAME_LENGTH, strData, strData, &CompCode, &Reason);
printf("Queue name: %s\n", strData);
}
mqInquireString(replyBag, MQCA_Q_MGR_NAME, 0, MQ_Q_MGR_NAME_LENGTH, strData,
&strDataLen, NULL, &CompCode, &Reason);
if (CompCode == MQCC_OK && Reason == MQRC_NONE)
{
mqTrim(MQ_Q_MGR_NAME_LENGTH, strData, strData, &CompCode, &Reason);
printf("Queue manager name: %s\n", strData);
}
mqInquireInteger(replyBag, MQIA_TIME_SINCE_RESET, MQIND_NONE, &itemValue,
&CompCode, &Reason);
if (CompCode == MQCC_OK && Reason == MQRC_NONE)
{
printf("Time since reset: %ld\n", itemValue);
}
mqInquireInteger(replyBag, MQIA_HIGH_Q_DEPTH, MQIND_NONE, &itemValue,
&CompCode, &Reason);
if (CompCode == MQCC_OK && Reason == MQRC_NONE)
{
printf("High queue depth: %ld\n", itemValue);
}
mqInquireInteger(replyBag, MQIA_MSG_ENQ_COUNT, MQIND_NONE, &itemValue,
&CompCode, &Reason);
if (CompCode == MQCC_OK && Reason == MQRC_NONE)
{
printf("Enqueue count: %ld\n", itemValue);
}
mqInquireInteger(replyBag, MQIA_MSG_DEQ_COUNT, MQIND_NONE, &itemValue,
&CompCode, &Reason);
if (CompCode == MQCC_OK && Reason == MQRC_NONE)
{
printf("Dequeue count: %ld\n", itemValue);
}
} /* endif */
} /* endwhile */
/***************************************************************************/
/* Delete the response bag if successfully created. */
/***************************************************************************/
if (replyBag != MQHB_UNUSABLE_HBAG)
{
mqDeleteBag(&replyBag, &CompCode, &Reason);
CheckCallResult("Delete the response bag", CompCode, Reason);
}
/******************************************************************/
/* close the event queue - if it was opened */
/******************************************************************/
if (OpenCode != MQCC_FAILED)
{
C_options = 0;
MQCLOSE(Hcon, &Hobj, C_options, &CompCode, &Reason);
}
/******************************************************************/
/* Disconnect from queue manager (unless previously connected) */
/******************************************************************/
if (CReason != MQRC_ALREADY_CONNECTED)
{
MQDISC(&Hcon, &CompCode, &Reason);
}
}
void CheckCallResult(char *callText, MQLONG cc, MQLONG rc)
{
if (cc != MQCC_OK)
{
printf("%s failed: Completion Code = %d : Reason = %d\n", callText, cc, rc);
}
}
|
Charlie |
|
Back to top |
|
 |
jed |
Posted: Mon Jun 14, 2004 1:12 am Post subject: |
|
|
 Centurion
Joined: 08 Jan 2004 Posts: 118 Location: MI, USA
|
Hi Charlie,
Lemme take a look at your codes and try it out.
I'm tired, had to work even on weekends from 8am to 11pm. Whew!!!
Rgds,
Dino _________________ Jed |
|
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
|
|
|
|