最初发布on Server Fault,有人建议在这里提出这个问题。
我们正在使用JBoss运行两个WAR。一个是我们的网络应用程序,另一个是我们的Web服务。 Web应用程序访问另一台计算机上的数据库并向Web服务发出请求。 Web服务向其他计算机发出JMS请求,聚合数据并返回它。
在我们最大的客户端,大约每月一次,JBoss Java进程占用所有CPU的100%。运行JBoss的机器有8个CPU。我们的网络应用程序在此期间仍可访问,但页面加载大约需要3分钟。重启JBoss会恢复正常。
数据库机器和所有其他机器都很好,只有运行JBoss的机器受到影响。内存使用情况正常。网络利用率是正常的。 JBoss日志中没有可疑的错误消息。
我已经建立了一个尽可能接近客户端生产环境的测试环境,并且我已经完成了高达2倍并发用户数的负载测试。我没有得到我的测试环境来复制问题。
我们从哪里开始?我们如何缩小问题?
目前我们唯一的计划是等到生产中出现问题,然后进行一些调试以确定原因。到目前为止,人们刚刚在问题发生时重新启动了JBoss,以尽量减少停机时间。下次它发生时,他们会让开发人员看一看。问题是,下次发生时,可以采取哪些措施来确定原因?
我们可以在同一个盒子上设置一个单独的JBoss实例,并与Web服务分开安装Web应用程序。这样,当下一个问题发生时,我们将知道哪个WAR有问题(假设它是我们的代码)。尽管如此,这并没有缩小范围。
我应该启用JMX遥控器吗?这种方式下次出现问题时我可以与VisualVM连接,看看哪些线程正在占用CPU以及他们到底在做什么。但是,在生产环境中启用JMX远程是否存在重大缺陷?
还有另一种方法可以查看哪些线程正在占用CPU并获取堆栈跟踪以查看它们正在做什么?
还有其他想法吗?
谢谢!
答案 0 :(得分:7)
有一种快速而又脏的方法可以识别哪些线程占用了JBoss上的CPU时间。使用浏览器访问JMX控制台(通常在http://localhost:8080/jmx-console,但可能与您不同),查找名为ServerInfo
的bean,它有一个名为listThreadCpuUtilization
的操作,它会转储实际的每个活动线程使用的CPU时间,采用漂亮的表格格式。如果有一个行为不端,它通常会像拇指一样突出。
还有listThreadDump
操作将每个线程的堆栈转储到浏览器。
不如分析器好,但更容易获取基本信息。对于生产服务器来说,连接分析器通常是个坏消息,它非常方便。
答案 1 :(得分:3)
这通常发生在失控代码或对散列图的不安全线程访问中。一个简单的线程转储(kill -3,如@disown所说,或者在Windows控制台中使用ctrl-break)将揭示这个问题。
由于你无法使用测试重现它,我认为它闻起来像一个并发问题;通常很难让测试脚本表现得足够随机以捕获此类问题。
我通常会尝试使其标准操作过程来执行由于操作异常而重新启动的任何 JVM的线程转储,并且实际上需要捕获每月一次的事情。
答案 2 :(得分:1)
我认为您应该尝试使用一些负载测试来设置测试环境,以便重现您的问题。分析肯定有助于确定问题。
快速解决方法是下次使用kill -3杀死jboss以获得转储分析。我要检查的第二件事是你运行-server标志,你的gc设置是理智的。您还可以运行一些dstat来查看进程在锁定期间正在执行的操作。但同样 - 只需设置负载测试环境(通过EC2左右)来重现这一点就更安全了。
答案 3 :(得分:1)
如果您使用的是JBoss 5.1.0 EAP,Jboss中存在一个错误,他们也有一个修复程序。 这是URL: https://issues.jboss.org/browse/JBPAPP-5193