【发布时间】:2015-11-03 12:31:26
【问题描述】:
我有一个 java 应用程序在日志中没有任何异常而神秘死亡。我通过 bash script 在后台运行它,它包装了如下的 nohup:
nohup java -Xms6g -Xmx6g -jar myapp.jar 2>> stderr.txt >> /dev/null & echo $! > /tmp/myapp-pid
Java 应用程序占用大量内存,因此配置了 6GB 堆空间(在 64 位 JVM 上运行)。它运行了大约 8 个小时,然后默默地死了。日志中没有异常,什么都没有。
应用程序从 main 方法进入无限循环,轮询 AWS SQS 以获取消息并处理它们。这一切都包含在一个 try-catch 中,我正在登录 catch。应用程序在完成一个 while 循环后似乎退出,因为它记录了最后一行。例如应用程序将始终以“已成功处理”结束。
while(true) {
try {
// Logic to poll SQS and process the message
} catch (MyCustomException e) {
// Write to SQS dead letter queue (was throwing at this point)
// Delete message from original SQS
} catch (Throwable e) {
LOG.error(...);
} finally {
LOG.info("Processing time was...");
}
}
我不知道从哪里开始,因为我以为它会记录一些东西。谁能提供一些指针或一些 JVM 设置来配置以便我可以开始调查?
我想知道代码之外的东西是否可能导致错误。就像 JVM 崩溃一样?
更新 看起来这确实是一个编程错误。我不认为这是导致问题的原因,所以我没有将它添加到上面的代码路径中(现在刚刚添加),但我确实有另一个 catch 子句来捕获我创建的自定义异常。在那个捕获中,我试图将 SQS 消息移动到死信队列,但没有获得权限,因此被扔进了我没有处理的捕获中。
感谢所有帮助提出问题的人!
【问题讨论】:
-
您的记录器是否配置为记录级别 ERROR - 而不仅仅是 INFO ?
-
两个问题:你有一个日志就在“while”开始的地方吗?除了你提到的 8 小时,还有其他模式吗?
-
从您的循环结构来看,我猜您在循环中的某处至少有一个
break;命令...在这种情况下,请使用编辑器搜索并替换您的 @ 987654325@ 带有System.out.println("Breakng out of loop!");break;之类的命令,以确认您是否通过这些中断之一退出循环;如果是,请继续调查哪个中断被错误触发以及原因。 --- 或者在每个break;命令中添加断点,并使用分析器对其进行调试。 -
@tbsalling - 记录了错误,但信息级别不包括错误吗?
-
我见过很多由于日志框架进行缓冲而导致日志文件未更新的情况。因此,只要您正在寻找错误,宁愿拥有太多日志而不是不完整的日志;-) 您可以稍后在修复错误时调整它。看看 -XX:ErrorFile 和 -XX:HeapDumpPath