2010-03-15 196 views
4

最初发布on Server Fault,在那里有人建议这个问题可能会在这里更好地问。调试JBoss 100%CPU使用率

我们使用JBoss来运行我们的两个WAR。一个是我们的网络应用程序,另一个是我们的网络服务。 Web应用程序访问另一台计算机上的数据库并向Web服务发出请求。 Web服务向其他机器发出JMS请求,汇总数据并将其返回。

在我们最大的客户端,大约每月一次的JBoss Java进程占所有CPU的100%。运行JBoss的机器有8个CPU。我们的网络应用程序在这段时间内仍然可以访问,但页面大约需要3分钟才能加载。重新启动JBoss将一切恢复正常。

数据库机器和所有其他机器都很好,只有运行JBoss的机器受到影响。内存使用情况正常。网络利用率是正常的。 JBoss日志中没有可疑的错误消息。

我已经建立了一个尽可能接近客户端生产环境的测试环境,并且我已经完成了负载测试,其并发用户数量是2倍。我还没有得到我的测试环境来重现问题。

我们从哪里出发?我们如何缩小问题的范围?

目前我们唯一的计划是等到问题发生在自己的生产中,然后进行一些调试以确定原因。到目前为止,人们在发生问题时刚刚重新启动了JBoss以最大限度地缩短停机时间。下次发生时,他们会让开发人员看一看。问题是,下次发生时,可以做什么来确定原因?

我们可以在同一个盒子上设置一个单独的JBoss实例,并从Web服务中单独安装Web应用程序。这样,当下一个问题发生时,我们将知道哪个WAR有问题(假设它是我们的代码)。尽管如此,这并没有缩小范围。

我应该启用JMX remote吗?通过这种方式,下次发生问题时,我可以使用VisualVM进行连接,查看哪些线程在使用CPU,以及他们在做什么。但是,在生产环境中启用JMX远程控制是否有重大缺陷?

是否有另一种方法来查看哪些线程正在吃CPU,并得到一个堆栈跟踪,看看他们在做什么?

还有其他想法吗?

谢谢!

+0

你好。 您是否发现了JBoss问题的根源? 我们不时有同样的问题。 – 2010-05-19 15:47:13

+2

是的,对于延迟抱歉。我们有一个HashMap被两个线程同时写入。如果一个放置触发重新散布,则第二个放置可以导致两个映射节点相互指向。接下来的HashMap会触发一个无限循环。 – NateS 2010-06-06 08:09:03

回答

2

我认为你应该尝试设置一个测试环境,进行一些负载测试以重现你的问题。性能分析绝对有助于查明问题。

一个快速修复将是下一次杀死与杀-3的jboss为了得到转储分析。我要检查的第二件事是,你使用-server标志运行,并且你的gc设置是合理的。您也可以运行一些dstat来查看锁定过程中的过程。但是,再次 - 建立一个负载测试环境(通过EC2左右)来重现这一点可能更安全。

+0

我有一个测试环境设置,我一直在使用磨床来锤击它。我无法在那里重现问题。不知道为什么。也许我的测试不会运用相同或广泛的各种数据。我已经对我的测试进行了配置,以确保通常没有线程争用。我确实发现制作中没有使用-server,我向某人大吼一声。 :) GC设置是默认设置。这很糟糕吗?我一定会检查你列出的命令。 – NateS 2010-03-15 19:41:46

+0

+1线程转储 – 2010-03-15 19:43:54

+0

对不起,Nate,在您的文章中错过了负载测试部分。我真的需要在回答他们之前开始阅读帖子:) – 2010-03-15 19:54:29

3

这通常发生在失控代码或不安全的线程访问hashmaps。一个简单的线程转储(杀死-3,就像@disown说的,或者在Windows控制台中按ctrl-break)将会揭示这个问题。

由于你无法使用测试重现它,我认为它闻起来像一个并发问题;通常很难让测试脚本表现出足够的随机性来捕捉这种类型的问题。

我通常会尝试使其执行标准操作过程,以执行线程转储任何由于操作异常而重新启动的JVM,并且确实需要捕获那些每月一次的事情。

7

有一种快速和肮脏的方式来确定哪些线程正在使用JBoss上的CPU时间。使用浏览器访问JMX控制台(通常在http://localhost:8080/jmx-console,但可能会有所不同),寻找名为ServerInfo的bean,它有一个名为listThreadCpuUtilization的操作,它将每个活动线程使用的实际CPU时间转储为一个很好的表格格式。如果有一个行为不端,它通常会像拇指一样突出。

还有listThreadDump操作将每个线程的堆栈转储到浏览器。

不如分析器,但获得基本信息更简单的方法。对于生产服务器来说,连接分析器通常是个坏消息,这非常方便。

+0

我检查了这一点。这非常有用!尽管必须使用线程名称而不是ID来关联线程CPU利用率列表和线程堆栈跟踪。 – NateS 2010-03-19 07:55:11

+1

只是用它来跟踪我们环境中的某些东西。谢谢。 – mwilson 2012-02-27 20:31:10