我们使用JBoss来运行我们的两个WAR。 一个是我们的networking应用程序,另一个是我们的networking服务。 Web应用程序访问另一台计算机上的数据库并向Web服务发出请求。 Web服务向其他机器发送JMS请求,汇总数据并返回。
在我们最大的客户端,大约每月一次的JBoss Java进程占所有CPU的100%。 运行JBoss的机器有8个CPU。 我们的networking应用程序在这段时间仍然可以访问,但是页面大约需要3分钟才能加载。 重新启动JBoss恢复一切正常。
数据库机器和所有其他机器都很好,只有运行JBoss的机器受到影响。 内存使用情况正常。 networking利用率是正常的。 JBoss日志中没有可疑的错误消息。
我已经build立了一个尽可能接近客户端生产环境的testing环境,并且已经完成了多达两倍的并发用户负载testing。 我还没有得到我的testing环境来复制这个问题。
我们从哪里出发? 我们怎样才能缩小这个问题?
目前我们唯一的计划是等到问题发生在自己的生产中,然后做一些debugging来确定原因。 到目前为止,人们刚刚重新启动JBoss,当问题发生,以最大限度地减less停机时间。 下次发生的时候,他们会让开发者看一看。 问题是,下次发生什么事情可以做,以确定原因?
我们可以在同一个盒子上设置一个单独的JBoss实例,并从Web服务中单独安装Web应用程序。 这样当下一个问题发生时,我们将知道哪个WAR有问题(假设它是我们的代码)。 尽pipe如此,这并没有缩小范围。
我应该启用JMX远程吗? 这样下一次发生问题时,我可以连接到VisualVM,看看哪些线程正在使用CPU,他们在做什么。 但是,在生产环境中启用JMX远程控制是否有重大缺陷?
有没有另外一种方法来看看哪些线程正在吃CPU,并得到一个堆栈跟踪,看看他们在做什么?
任何其他的想法?
谢谢!
您可以发送一个SIGQUIT信号给正在运行的JVM,以便将每个线程的堆栈跟踪打印到标准输出。 这并不杀死这个进程,虽然我认为它确实让所有的线程在打印堆栈跟踪的同时进入hibernate状态。
然后,将列出的线程ID与首选的看线程CPU利用率的方法相关联。 用于Solaris的prstat -L ,用于Linux的top -H 。 请注意,java堆栈跟踪中的tid是以hex打印的; 与顶部或prstat输出相比,您可能不得不将其转换为十进制。
我做了一个线程转储。 但是,在我的生产系统上,除非JVM以某些我们决不会在生产中启用的参数启动,否则无法完成。 在这种情况下,我使用JMX控制台的jboss.system:type = ServerInfo mbean来执行线程转储(listThreadDump())。
当我没有编写代码时,线程转储输出对我来说是毫无意义的。 但是编写代码的人也许可以理解它。 在这些线程转储没有帮助的情况下,我更喜欢使用“ strace -fp <PID of JBoss' java process> -o outfile.txt ”来进一步查看系统调用级别正在发生的事情。 这有点像从水龙头喝水,但有时候会有帮助。