1

我正在使用 WebSphere MQ 7,我有两个客户端连接到同一个 QMgr 并使用来自同一个队列的消息,如下面的代码:

 while (true) {
        TextMessage message = (TextMessage) consumer.receive(1000);
        if (message != null) {
            System.out.println("*********************" + message.getText());
        }
    }

我发现只有一个客户端总是检索消息。有什么方法可以让两个客户端中的消费消息负载平衡?MQ 服务器端的任何配置选项?

4

2 回答 2

3

在管理队列句柄时,WMQ 将它们放入堆栈而不是 LIFO 队列要快得多。因此,如果消息到达队列的速度比处理它们的速度慢,那么一个实例可能会处理该消息并执行另一个 GET,WMQ 会将其下推到堆栈上。结果是只有一个实例会在低容量用例中看到消息。

在有许多实例在等待消息的较大环境中,活动可能会在这些实例的一部分之间循环,而其他实例则需要消息。例如,队列中有 10 个 GETter,您可能会看到 3 条正在处理的消息和 7 条空闲消息。

尽管这对于 MQ 来说要快得多,但对于不了解其内部工作原理的客户来说,这会让人感到困惑,因此他们会打开 PMR 来询问这个确切的问题。IBM 必须在以下几个备选方案中进行选择:

  • 添加多个代码路径以在完全加载时由堆栈管理以提高性能,而在轻负载时由 LIFO 管理以实现明显的平衡。这使代码膨胀,添加了许多新的决策点来引入错误,并解决了一个感知问题,而不是可靠性或性能问题。
  • 让客户了解它是如何工作的。当然,一旦你记录了它,你就不能改变它。我发现这一点的方式是参加 IMPACT 的“WMQ Internals”演示文稿。它不在 Infocenter 中,因此 IBM 可以更改它,但它可供客户使用。
  • 没做什么。尽管从代码设计的角度来看这是最好的结果,但这种行为是违反直觉的。用户需要了解为什么事情没有按预期运行,并且会浪费时间尝试找到导致所需行为的配置,或者打开 PMR。

我不确定它是否仍然以这种方式工作,但我希望它确实如此。我过去测试它的方法是一次将许多消息放在队列中,然后查看它们是如何分布的。如果您在一个工作单元中将大约 50 条消息放入队列中,您应该会看到两个实例之间的分布更好。

如何一次将 50 条消息放到队列中?首先在应用程序关闭或备用队列的情况下生成它们。如果您在目标队列中生成它们,请使用Q 程序将它们移动到备用队列。现在启动应用程序并确保队列的IPPROC计数等于您启动的应用程序实例的数量。再次使用 Q,将所有消息复制到单个工作单元中的原始队列。由于它们都立即在队列中可用,因此您的两个应用程序实例都应立即传递一条消息。如果您使用复制而不是移动,则可以根据需要多次重复此操作。

于 2012-12-10T17:54:44.347 回答
0

您的客户端没有做太多事情,因此一个实例可能可以处理全部负载。尝试实现一个更现实的工作负载,或者更简单,在客户端中放置一个 Thread.sleep。

于 2012-12-10T12:36:07.497 回答