0

我们在 CentOS 6.3 上使用 HornetQ 2.2.14。我们在我们的应用服务器中遇到了 CPU 使用率高的问题,并已使用分析器将其缩小到我们的 HornetQ 消费者。

具体来说,我们在大约有 150 个消费者的空队列上快速连续调用此方法:

// Called about every 10ms per consumer.
javax.jms.MessageConsumer.receive(10);

这导致大约 2 个 NIO 工作线程回溯到 Netty,在我们原本空闲的 Tomcat 实例上消耗了大约 2 个 CPU 内核的 50%。

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
21939 tomcat    20   0 9061m 1.6g  16m R 55.4 21.2   1:06.88 java
21777 tomcat    20   0 9061m 1.6g  16m S 47.6 21.2   1:29.40 java
21777 tomcat    20   0 9061m 1.6g  16m S  7.3 21.2   1:33.41 java
21763 tomcat    20   0 9061m 1.6g  16m S  6.6 21.2   1:28.84 java
21682 tomcat    20   0 9061m 1.6g  16m S  4.3 21.2   0:26.70 java

问题是,在 Windows 上使用完全相同的代码和 Tomcat 配置,CPU 内核是空闲的。这让我相信这是一个 Linux/Netty/HornetQ 问题。以前有没有其他人见过这个,如果是这样,我该如何让它消失?

Linux版本:CentOS 6.3 x64 Linux内核版本:Linux版本2.6.32-279.19.1.el6.x86_64

以下是我测试过的 2 个 Java 版本,结果相同:

Java(TM) SE Runtime Environment (build 1.7.0_10-b18)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

Java(TM) SE Runtime Environment (build 1.6.0_38-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)
4

2 回答 2

2

IMO你应该使用MessageListener ..或者只是阻塞更长的时间,比如10秒......

... 10 毫秒重复对您的系统来说是一个巨大的爆发。特别是客户端每次都会向服务器发送回调。

让消息系统为你做这些工作,即当消息到达时让它呼叫你。如果您每 10 毫秒轮询一次系统,那么您将无法期待其他任何事情。

正如您自己所指出的,这是您问题的罪魁祸首:

consumer.receive(10);

算一下,您使用此接收(10)锤击服务器的每个消费者正在使服务器每秒向您发送 100 条消息,每个消费者说...我是空的。

receive(10) 将进行往返以保证没有消息在传输中。因此,您正在用空消息锤击服务器。

根据您强制它的参数,您的应用程序不应该表现良好。对于任何保证在返回 null 之前接收(10)为空的消息解决方案。

于 2013-02-05T16:02:35.543 回答
1

虽然克莱伯特的回答有点难以接受,但它最终是一个有效的案例。您可以轻松地创建多个消息侦听器,这些侦听器将充当您的工作人员并允许 JMS 提供者调用它们。假设您的目的地是某种队列,消息侦听器将以相当分散的负载被调用,以允许多个线程处理处理。创建消息侦听器将允许 JMS 提供者在消息到达时调用它们,而不是等待您的客户端使用消息。

每次调用接收方法时,它都会按照 Clebert 描述的方式运行(他应该知道,他是 HornetQ 的负责人)。

我不确定 Netty HornetQ 2.2.14 的版本,但我确实在 github 上的 repos 中发现了一些与非常相似的问题相关的问题。也许您可以尝试在您的应用程序中更新 Netty 的版本,看看是否有帮助?

https://github.com/netty/netty/issues/592

https://github.com/netty/netty/issues/582

于 2013-03-02T22:20:39.917 回答