我有一个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小时,然后默默地死亡。日志中没有例外,没有。
从主方法app进入无限循环,轮询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子句捕获我创建的自定义Exception。在那个捕获中,我试图将SQS消息移动到死信队列但是没有权限,因此扔进了我没有处理的捕获。
感谢所有帮助建议可能出错的人!
答案 0 :(得分:1)
如果没有更多代码,很难说实际发生了什么。 但是根据最终的定义,它总是被执行,这也意味着在失败的情况下。也许你只是错过了之前写的异常。 尝试在'try'-block中移动finally调用。
while(true) {
try {
// Logic to poll SQS and process the message
LOG.info("Successfully processed");
} catch (Throwable e) {
//As mentioned in the comments try for debugging to log on info level here as well.
// Maybe error level is disabled (although this should be
//very unlikely since error normally is written too when info is written.
LOG.info(...);
} finally {
//Clean up.
}
}
这两个想法可能会帮助您进一步调查您的问题。
答案 1 :(得分:1)
你的系统内存不足吗?尝试从包装脚本运行应用程序,记录退出代码 - int[] x = new int[5];
x[10] = 2;
。
同时运行echo $! >&2
可以告诉您oom杀手是否选择ypur应用作为受害者。