我已经构建了一个小型Java程序,该程序使用MQ客户端类与Websphere MQ服务器及其队列进行对话。我想要的是定期查询某个队列的大小,错误深度。每10秒。
我所做的,示意性地:
qm = new MQQManager()
q = qm.accessQueue()
depth = q.getCurrentDepth()
depth
做些事)q.close()
qm.close()
这就像一个魅力!
出于懒惰,我编写了代码,每次都要经过上述序列的所有6个步骤。因此,我最终每10秒重复一次此循环。在大约半小时内,监视服务器的人员告诉我,我已打开153个实例。显然,仅在队列和QM上执行
close()
不足以自己清理。我将进行明显的修复,并保持QM并排队等待程序的生命周期。但是有人可以告诉我为什么我以前的方法会泄漏资源吗?如果我选择遵循这种方法,我该怎么办?
更新(2017-01-25)
计时和接受
关于性能和未提交的消息,Roger提供了一些漂亮的代码和一些有用的解释。太酷了,但是Eugene的回答恰好(并且最少)足以解决我的问题,而且他的回答要快一些。在根据Eugene的建议将
close()
更改为disconnect()
之后,我的小应用程序现在可以完全满足我的要求。现在我对谁应该获得复选标记感到不安。我对你们俩表示歉意!我已经完全满足了我的要求,并且我想我已经解决了这个问题,但是我还要补充一点,我感谢Roger为该问题提供的有用信息,为以后的任何其他读者提供了周到的解答。希望其他人会听他的话,而不是跟随我。
性能
老实说,我不对表现一无所知。该服务器比当前执行的操作所需的胖得多,并且我的监视客户端(此问题的主题)在通常为空的开发计算机上运行。我希望它在一两天内能达到目的,然后我将其丢弃。同时,如果每10秒连接一次会导致性能问题,则它们应该平衡Raspberry Pi或其他设备的负载。
未提交的邮件
我认为这也不是问题。发送应用程序在几毫秒内以大约1-5条消息的小批量入队,并立即提交。接收应用程序(我写的一个客户端,很可能有问题)不断地在队列上侦听,分别接收和确认(提交)每条消息。因此,我有把握地确定不会超过1条,可能是5条未确认的消息。与...的参数相比,该数字微不足道。
我的实际问题,
每天早上几乎同一时间,其中涉及几到几百条消息的处理延迟在5到20分钟之间。我怀疑我的接收客户端因MQS以外的“挂起”网络IO操作而停滞了。我要探索的第一步是证明MQS上确实存在队列中的等待消息,并且没有被接收。我想看看该队列何时开始建立,它坐在那里多长时间以及一旦我的客户再次醒来它消退的速度如何。
这种连接每天可看到2,000至10,000条消息,其峰值对应于下午和晚上的批处理过程,但是延迟仅在早晨发生,通常实际发送的消息量很小。我想查看队列大小的日志,以更好地了解正在发生的事情。下一步,我可能需要在接收客户端中进行更多检测。
环境
就其价值而言,服务器正在运行WSMQ 6,因此我的客户端使用阻塞等待队列获取,而不是我本来希望使用的灵活的异步通知过程。我的接收客户端是在VM中的RHEL下运行的独立C应用程序。
最佳答案
哇!不是很有效的代码。通过FAR进行连接是最昂贵的MQ API调用。同样,获得队列深度是没有意义的。它为您提供队列中所有未提交和已提交的消息。即队列深度可能表示队列中有5条消息,但是您的程序只能检索3条消息!您可能会说MQ坏了,但实际上,没有提交2条消息,因此,消费者无法使用。
如果您真的想每10秒获取和记录一次信息,请保持联系。
这是一种更好的方法:
boolean working = true;
int openOptions = CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING;
int depth = 0;
MQQueueManager qm = null;
MQQueue q = null;
try
{
qm = new MQQueueManager("MQA1");
while (working)
{
try
{
q = qm.accessQueue("TEST.Q1", openOptions);
depth = q.getCurrentDepth();
// (do something with depth)
}
catch (MQException e)
{
System.out.println("CC = " + e.completionCode + " : RC=" + e.reasonCode);
System.out.println(e.getLocalizedMessage() );
working = false;
}
finally
{
if (q != null)
{
q.close();
q = null;
}
}
try
{
if (working)
Thread.sleep(10*1000); // time in milliseconds
}
catch (InterruptedException ie) {}
}
}
catch (MQException e)
{
System.out.println("CC = " + e.completionCode + " : RC=" + e.reasonCode);
System.out.println(e.getLocalizedMessage() );
}
finally
{
try
{
if (q != null)
q.close();
}
catch (MQException e)
{
System.out.println("CC = " + e.completionCode + " : RC=" + e.reasonCode);
System.out.println(e.getLocalizedMessage() );
}
try
{
if (qm != null)
qm.disconnect();
}
catch (MQException e)
{
System.out.println("CC = " + e.completionCode + " : RC=" + e.reasonCode);
System.out.println(e.getLocalizedMessage() );
}
}
关于java - 如何避免太多的IBM MQ channel 实例?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41815989/