我一直在处理我写的服务器的问题。它在Clojure中,但我认为这并不重要,我们可以假装它是用Java编写的。无论如何,它一次可以正常工作几个小时,但是在它表现非常糟糕的情况下进入适合:所有活动停止,大约十五秒,然后它正常工作几秒钟,然后停止十五秒......等等(通常)大约十分钟左右,然后恢复正常行为。
我用YourKit做了很多分析,我排除了一些看似合理的嫌疑人:
这不是垃圾收集问题:我正在使用-XX:+UseConcMarkSweepGC
运行它,并且我已经验证服务器在次要和主要集合期间继续运行正常,这是由于并发性质这个垃圾收集器。当我们耗尽总内存或其他东西时,我们并没有挣扎:当前的堆大小远低于其最大值。
我认为这不是一个锁定/同步问题,但我并不是100%肯定。 YourKit探查器有时会显示等待的线程,例如通过锁定来竞争System.out以生成日志消息,但是当没有任何事情要做时,唯一的长等待是线程池中的工作线程。当然,YourKit说它从来没有发现任何死锁。
这不是因为连接了探查器而引起的,因为即使我启动服务器然后在不附加探查器的情况下单独使用它仍然会发生。
系统占用所有CPU时间不是其他一些过程:top
表示我的java进程的CPU使用率为100%,其他所有内容的CPU使用率基本为0%。
我最大的问题是,在这些奇怪的问题中我无法看到服务器正在做什么,因为探查器停止接收样本。这是CPU使用率图表的图表:
图表的左侧是正常操作,在此期间我们每秒钟左右获取一次探查器样本。右侧是“破碎的”,并且非常尖刻,因为探测器每10秒左右才会获取样品。在它确实得到的样本中,服务器似乎正在做其通常的业务:响应请求等等;并且日志确认它正在做正常的事情,但仅在探查器有样本的时候:在图表上向上倾斜的“直线”期间,探查器没有样本,服务器什么都不做。
那么,这个图表对任何人来说都很熟悉吗?你以前遇到过这个问题并修好了吗?或者你能指出一个工具的方向,可以找出我的服务器在YourKit不能做的时候做了什么吗?如果重要,服务器机器正在运行Ubuntu 10.04和
$ java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.10) (rhel-1.28.1.10.10.el5_8-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
答案 0 :(得分:2)
好的,从评论中我很清楚,到目前为止,我们无法用你提供的信息来解决这个问题。我们所能做的最好的就是如何调试它...
我会尝试在其中一个峰值期间使用jstack,看看你是否可以用它来弄清楚它挂在哪里。
答案 1 :(得分:0)
如果您没有机会在代码中进行测量或调试,请尝试从外部进行查看。
我首先会尝试重现这个问题。换句话说,是否存在产生行为的外部事件。尝试更改服务器上的负载。切换所有可以重现问题的东西。
也许在服务器挂起时,嗅探网络流量(tcpdump)以找到有趣的东西也是个好主意。
您也可以在其他操作系统上运行它,以检查它是否取决于您的安装环境。
如果无法重现出现问题的情况,请尝试查找无法解决问题的情况。例如,从net中删除服务器。关闭所有其他服务。
如果您无法找到程序的任何行为更改,请尝试降低工作代码的复杂性,并查看是否可以找到似乎与问题相关的内部模块。
答案 2 :(得分:0)
你以前遇到过这个问题并修好了吗?或者你能指点我吗? 可以找出我的服务器正在做什么的工具的方向 在YourKit不能的时候?
如果您在服务器上有shell访问权限并且可以看到stdout,请尝试在服务器无响应时进行线程转储。不确定这是否会给你与jstack(在另一个答案中提到)给你的不同之处。
在Ubuntu上:kill -QUIT <java-pid>
(实际上不会杀死Java进程)。
http://www.crazysquirrel.com/computing/java/basics/java-thread-dump.jspx