【问题标题】:How to run a Java console application all the time?如何始终运行 Java 控制台应用程序?
【发布时间】:2016-11-25 11:09:31
【问题描述】:

我有一台服务器(Ubuntu 14.04.4 LTS),并希望某个 Java 应用程序一直在其上运行。目前我使用nohup gradle run & 启动它。昨天它停止工作了。 nohup.out 显示以下错误消息:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':run'.
> Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 137

我需要如何更改我的 Java 应用程序以防止将来出现此类错误(确保应用程序一直运行,并且 - 理想情况下 - 如果它崩溃了会自动重新启动)?我正在寻找简单、最少的解决方案。

请注意,我之前在这家特定公司的服务器上遇到过类似问题。我有一个带有 Web 应用程序的 Apache 服务器,有时它会无缘无故地停止工作(也许服务器由于活动不足而进入睡眠状态,不知道)。

更新 1(27.01.2017 12:30 MSK):我修改了 Gradle 代码以在 OutOfMemoryError 的情况下记录内存转储。

run {
    jvmArgs = ["-Xmx100m", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/home/dp/dev/myprod/log/memdump.log"]
}

当我运行 Gradle 脚本时,我在输出中看到以下消息,从中我得出结论,内存转储参数定义正确。

09:33:47.031 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'command '/usr/lib/jvm/java-8-oracle/bin/java''. Working directory: /home/dp/dev/myprod Command: /usr/lib/jvm/java-8-oracle/bin/java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/dp/dev/myprod/log/memdump.log [...] com.mycompany.myprod.AppKt

应用程序崩溃后,我没有看到文件/home/dp/dev/myprod/log/memdump.log。目录/home/dp/dev/myprod/log/ 存在并且可供启动应用程序的用户访问。

我使用nohup gradle --full-stacktrace --stacktrace --debug run & 启动应用程序,但它无助于获取有关问题原因的任何有意义的信息。

这是我得到的例外:

06:29:16.179 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Caused by: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with non-zero exit value 137
06:29:16.180 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:369)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.process.internal.DefaultJavaExecAction.execute(DefaultJavaExecAction.java:31)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.tasks.JavaExec.exec(JavaExec.java:74)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
06:29:16.186 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:136)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:129)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:118)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:623)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:606)
06:29:16.187 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
06:29:16.188 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
06:29:16.194 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   ... 68 more
06:29:16.205 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] 

【问题讨论】:

  • 137 内存不足。你可能有内存泄漏
  • 你也可以在你的标题上工作
  • 你是把它作为一个简单的“java应用程序”运行还是在像tomcat这样的服务器上运行?你在用詹金斯吗?
  • @RudiDudi 简单的 Java(实际上是 Kotlin)应用程序。我既不使用 Tomcat,也不使用 Jenkins。
  • @PhilippSander 查看我的更新 1. 在没有内存转储的情况下如何诊断 OutOfMemoryError?

标签: java linux gradle ubuntu-14.04 daemon


【解决方案1】:
  1. 基本上,这不是一个好习惯。您应该避免使用构建工具,并在运行前将其打包到可执行 JAR 中。如果您出于某种原因需要在启动期间解决工件,请查看 Capsule projectGradle Capsule Plugin

  2. Gradle 3.+ 默认使用守护进程。如果它已闲置 3 小时或更长时间,Gradle 将杀死守护进程。我不确定是不是这个原因,但是您可以尝试从--no-daemon 参数开始。

【讨论】:

  • 我创建了一个胖 JAR 并在 24 小时前启动了它。到目前为止,应用程序没有问题。所以你可能是对的。
【解决方案2】:

正如 cmets 中所说,这是一个内存不足异常,您可以这样做:

Rewiev 你的代码,也许你的代码性能低下。

如果您正在运行一个简单的“java 应用程序”,则可以单击“Run As.. Java Application”,单击“Run As.. Run Configration”,选择您的 java 应用程序,然后在 TAB 中的“Arguments”、“VM Arguments” " 添加此参数:

-Xmx1024m -Xms512m 

使用此参数,您可以在应用程序上分配最少 512M(在开始时),最多分配 1024M。您可以根据需要放大此数字。

【讨论】:

  • 这不能修复内存泄漏!
【解决方案3】:

首先,您应该尝试查找并解决应用程序中的内存不足问题。

要设置监控,您可以编写一个简单的脚本来检查您的应用程序是否正在运行。 检查应用程序是否正在侦听指定端口或使用

ps aux 

或任何其他适合您的方式。

如果应用程序关闭,请重新启动它。

现在设置一个每隔几分钟运行一次此脚本的 cron。 像

*/10 * * * * /your/script

这将每 10 分钟运行一次您的脚本。

【讨论】:

    猜你喜欢
    • 2013-02-11
    • 2013-03-01
    • 1970-01-01
    • 2017-04-04
    • 2014-05-18
    • 2012-12-07
    • 1970-01-01
    • 2019-01-30
    • 2014-04-30
    相关资源
    最近更新 更多