【问题标题】:When multi MessageConsumer connect to same queue(Websphere MQ),how to load balance message-consumer?当多个 MessageConsumer 连接到同一个队列(Websphere MQ)时,如何对消息消费者进行负载平衡?
【发布时间】:2012-11-27 20:37:16
【问题描述】:
我正在使用 WebSphere MQ 7,我有两个客户端连接到同一个 QMgr 并使用来自同一个队列的消息,如以下代码:
while (true) {
TextMessage message = (TextMessage) consumer.receive(1000);
if (message != null) {
System.out.println("*********************" + message.getText());
}
}
我发现只有一个客户端总是检索消息。有什么方法可以让两个客户端中的消费消息负载平衡? MQ 服务器端的任何配置选项?
【问题讨论】:
标签:
jms
websphere
load-balancing
ibm-mq
【解决方案1】:
您的客户端没有做太多事情,因此一个实例可能可以处理全部负载。尝试实现一个更现实的工作负载,或者更简单,在客户端中放置一个 Thread.sleep。
【解决方案2】:
在管理队列句柄时,WMQ 将它们放入堆栈而不是 LIFO 队列要快得多。因此,如果消息到达队列的速度比处理它们的速度慢,那么一个实例可能会处理该消息并执行另一个 GET,WMQ 会将其下推到堆栈上。结果是只有一个实例会在低容量用例中看到消息。
在有许多实例在等待消息的较大环境中,活动可能会在这些实例的一部分之间循环,而其他实例则需要消息。例如,队列中有 10 个 GETter,您可能会看到 3 个正在处理的消息和 7 个空闲。
虽然这对于 MQ 来说要快得多,但对于不了解其内部工作原理的客户来说,这会让人感到困惑,因此他们会打开 PMR 来询问这个确切的问题。 IBM 必须在几个备选方案中做出选择:
- 添加多个代码路径以在完全加载时由堆栈管理以提高性能,而在轻负载时由 LIFO 管理以实现明显的平衡。这会使代码膨胀,添加许多新的决策点来引入错误并解决一个与感知而非可靠性或性能有关的问题。
- 向客户介绍其工作原理。当然,一旦你记录了它,你就不能改变它。我发现这一点的方式是参加 IMPACT 的“WMQ Internals”演示文稿。它不在信息中心,因此 IBM 可以更改它,但它可供客户使用。
- 什么都不做。尽管从代码设计的角度来看这是最好的结果,但这种行为是违反直觉的。用户需要了解为什么事情没有按预期运行,并且会浪费时间尝试找到导致所需行为的配置或打开 PMR。
我不确定它是否仍然以这种方式工作,但我希望它确实如此。我用来测试它的方法是一次将许多消息放在队列中,然后查看它们是如何分布的。如果您在一个工作单元中将大约 50 条消息放入队列中,您应该会看到两个实例之间的分布更好。
如何一次将 50 条消息放到队列中?首先在应用程序关闭或备用队列的情况下生成它们。如果您在目标队列中生成它们,请使用Q program 将它们移动到备用队列。现在启动应用程序并确保队列的IPPROC 计数等于您启动的应用程序的多个实例。再次使用 Q,将所有消息复制到单个工作单元中的原始队列。由于它们都立即在队列中可用,因此您的两个应用程序实例都应该立即传递一条消息。如果您使用复制而不是移动,则可以根据需要多次重复此操作。