当多MessageConsumer连接到同一队列(Websphere MQ)时,如何对消息使用者进行负载均衡?

时间:2012-12-10 12:18:56

标签: jms websphere load-balancing ibm-mq

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

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

我发现只有一个客户端总是检索邮件。有没有方法让两个客户端中的消费 - 消息负载平衡? MQ Server端的任何配置选项?

2 个答案:

答案 0 :(得分:2)

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

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

尽管MQ的速度要快得多,但对于那些不了解内部工作方式的客户来说却很困惑,所以他们打开PMR询问这个问题。 IBM必须在几种选择中做出选择:

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

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

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

答案 1 :(得分:0)

您的客户端做得不多,因此一个实例可能可以处理满负荷。尝试实现更现实的工作负载,或者更简单的是,将Thread.sleep放在客户端中。